使用 RESTFul API

REpresentational State Transfer(REST) 是一種用於 Web 開發的架構風格,由 Roy Fielding 在 2000 年引入和定義。

在 wiki 上看到它: REST wiki

它基於 HTTP 協議( Wiki 上的 HTTP ),HTTP 請求(GET,POST,PATCH,DELETE …)/響應程式碼(404,400,200,201,500 ……)和主體結構。

這是將資料暴露給 Internet 上另一個系統的好方法。

想象一下,你想製作一個 RESTFul api 來管理本地資料庫上的 StackOverFlower(使用者)。

讓我們舉個例子吧!

Symfony 2.8 框架

  1. 網路伺服器 :

你必須在本地計算機上安裝和配置 Web 伺服器,請參閱 WampLampMamp :你必須擁有最新版本的 PHP( !!! Symfony 要求!!!

  1. Php cli 和作曲家:

你必須配置 PHP cli(在我們的系統上有所不同),在我們的朋友 Google 中輸入“PHP cli [OS-NAME] how-to”! 你必須安裝 composer,請參閱 Composer 安裝

  1. Symfony:

你必須安裝 Symfony 2.8(使用 composer,這是更好的方法),開啟終端(或 Windows 上的 cmd)並轉到 Web 伺服器路徑。

Symfony 2 使用了一種更好的結構型別:Bundles。所有都是 Symfony 的套裝! 我們可以在上面測試它。

cd /your-web-server-path/
composer create-project symfony/framework-standard-edition example "2.8.*"

轉到樹結構,請參閱:Symfony 2.8 安裝在 example 目錄中。

  1. JMSSerializer Bundle 上的 FOSRest(適用於 FriendsOfSymfony):

你必須安裝這兩個 Bundles:

JMSSerializer( 安裝 ):

composer require jms/serializer-bundle "~0.13"

FosRestBundle( 安裝 ):

composer require friendsofsymfony/rest-bundle

別忘了在 AppKernel.php 中啟用它們!

  1. 基本配置:

製作你自己的示例包並建立資料庫。

cd /path/to/your/symfony/
php app/console generate:bundle
php app/console doctrine:generate:database

轉到 Symfony 2.8 應用程式配置檔案的底部,然後貼上它:

#app/config/config.yml
fos_rest:
    format_listener:
        rules:
            - { path: '^/stackoverflower', priorities: ['xml', 'json'], fallback_format: xml, prefer_extension: true }
            - { path: '^/', priorities: [ 'text/html', '*/*'], fallback_format: html, prefer_extension: true }

建立你的 doctrine 目錄(“example / src / ExampleBundle / Entity”)和資原始檔(“StackOverFlower.orm.yml”):

# src/ExampleBundle/Resources/config/doctrine/StackOverFlower.orm.yml
ExampleBundle\Entity\StackOverFlower:
    type: entity
    table: stackoverflower
    id:
        id:
            type: integer
            generator: { strategy: AUTO }
    fields:
        name:
            type: string
            length: 100

生成實體和更新架構:

php app/console doctrine:generate:entity StackOverFlower
php app/console doctrine:schema:update --force

製作預設控制器:

#src/ExampleBundle/Controller/StackOverFlowerController.php

namespace ExampleBundle\Controller;

use FOS\RestBundle\Controller\FOSRestController;
use Symfony\Component\HttpFoundation\Request;

use FOS\RestBundle\Controller\Annotations\Get;
use FOS\RestBundle\Controller\Annotations\Post;
use FOS\RestBundle\Controller\Annotations\Delete;

use ExampleBundle\Entity\StackOverFlower;

class StackOverFlowerController extends FOSRestController
{
    /**
     * findStackOverFlowerByRequest
     * 
     * @param Request $request
     * @return StackOverFlower
     * @throws NotFoundException
     */
    private function findStackOverFlowerByRequest(Request $request) {
        
        $id = $request->get('id');
        $user = $this->getDoctrine()->getManager()->getRepository("ExampleBundle:StackOverFlower")->findOneBy(array('id' => $id));
        
        return $user;
    }
    
    /**
     * validateAndPersistEntity
     * 
     * @param StackOverFlower $user
     * @param Boolean $delete
     * @return View the view
     */
    private function validateAndPersistEntity(StackOverFlower $user, $delete = false) {
        
        $template = "ExampleBundle:StackOverFlower:example.html.twig";
        
        $validator = $this->get('validator');
        $errors_list = $validator->validate($user); 
        
        if (count($errors_list) == 0) {
            
            $em = $this->getDoctrine()->getManager();
            
            if ($delete === true) {
                $em->remove($user);
            } else {
                $em->persist($user);
            }
            
            $em->flush();
            
            $view = $this->view($user)
                         ->setTemplateVar('user')
                         ->setTemplate($template);
        } else {
            
            $errors = "";
            foreach ($errors_list as $error) {
                $errors .= (string) $error->getMessage();  
            }
            
            $view = $this->view($errors)
                         ->setTemplateVar('errors')
                         ->setTemplate($template);
            
        } 
        
        return $view;
    }
    
    /**
     * newStackOverFlowerAction
     * 
     * @Get("/stackoverflower/new/{name}")
     * 
     * @param Request $request
     * @return String
     */
    public function newStackOverFlowerAction(Request $request)
    {   
        $user = new StackOverFlower();
        $user->setName($request->get('name'));
        
        $view = $this->validateAndPersistEntity($user);
            
        return $this->handleView($view);
    }
      
    /**
     * editStackOverFlowerAction
     * 
     * @Get("/stackoverflower/edit/{id}/{name}")
     * 
     * @param Request $request
     * @return type
     */
    public function editStackOverFlowerAction(Request $request) {
        
        $user = $this->findStackOverFlowerByRequest($request);
        
        if (! $user) {
            $view = $this->view("No StackOverFlower found for this id:". $request->get('id'), 404);
            return $this->handleView($view);
        }
        
        $user->setName($request->get('name'));
        
        $view = $this->validateAndPersistEntity($user);
                
        return $this->handleView($view);
    }
    
    /**
     * deleteStackOverFlowerAction
     * 
     * @Get("/stackoverflower/delete/{id}")
     * 
     * @param Request $request
     * @return type
     */
    public function deleteStackOverFlowerAction(Request $request) {
        
        $user = $this->findStackOverFlowerByRequest($request);
        
        if (! $user) {
            $view = $this->view("No StackOverFlower found for this id:". $request->get('id'), 404);
            return $this->handleView();
        }
        
        $view = $this->validateAndPersistEntity($user, true);
                
        return $this->handleView($view);
    }
    
    /**
     * getStackOverFlowerAction
     * 
     * @Get("/stackoverflowers")
     * 
     * @param Request $request
     * @return type
     */
    public function getStackOverFlowerAction(Request $request) {
        
        $template = "ExampleBundle:StackOverFlower:example.html.twig";
        
        $users = $this->getDoctrine()->getManager()->getRepository("ExampleBundle:StackOverFlower")->findAll();
        
        if (count($users) === 0) {
            $view = $this->view("No StackOverFlower found.", 404);
            return $this->handleView();
        }
        
        $view = $this->view($users)
                     ->setTemplateVar('users')
                     ->setTemplate($template);
        
        return $this->handleView($view);
    }
}

設定預設的 Twig 檢視:

#src/ExampleBundle/Resources/views/StackOverFlower.html.twig
{% if errors is defined %}
  {{ errors }}  
{% else %}
  {% if users is defined %}
    {{ users | serialize }}
  {% else %}
    {{ user | serialize }}
  {% endif %}
{% endif %}

你剛剛製作了第一個 RESTFul API!

你可以在以下位置進行測試: http://your-server-name/your-symfony-path/app_dev.php/stackoverflower/new/test

正如你在資料庫中看到的那樣,建立了一個名為 test 的新使用者。

你可以在以下網址獲取 stackoverflower 列表: http://your-server-name/your-symfony-path/app_dev.php/stackoverflowers

你在此示例的 github 帳戶上有一個完整的示例: Git Hub 示例 ,在此示例的 master 分支上,以及“real-routes”分支上的一個示例,其中包含更合適的 URL(如 POST 和 DELETE)。

稍後再見,以獲得 SOAP 的示例!

最好的祝福,

馬蒂厄