Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Создание легкого API средствами ZF2

fwdays
November 14, 2011

Создание легкого API средствами ZF2

Данный доклад представляет собой набор практик по проектированию, созданию и тестированию легковесных API, построенных на базе компонентов ZF2.

fwdays

November 14, 2011
Tweet

More Decks by fwdays

Other Decks in Programming

Transcript

  1. Список литературы Richardson Maturity Level (http://goo.gl/aYlT) The REST Architectural Style

    (http://goo.gl/DxTPB) Separating REST Facts from Fallacies (http://goo.gl/Xik2A) Roy Fielding’s Dissertation (http://goo.gl/Q71Y) Haters gonna HATEOS (http://goo.gl/1lrLu) Vendor Specific Mime Types - RFC4288 (http://goo.gl/o0fu6) Saturday, November 12, 2011
  2. Об авторе ZF Hacker Phrozn (phrozn.info) Phing (phing.info) zftalk.dev (zf.rpod.ru)

    @farazdagi github.com/farazdagi Saturday, November 12, 2011
  3. Стуктура доклада 1. Потребность в API 2. Проектирование 3. Создание

    4. Тестирование 5. Поддержка Saturday, November 12, 2011
  4. Плюсы создания API Developers, developers, developers, developers!! Более продуманная архитектура

    Доступность данных Превращение конкурентов в партнеров Saturday, November 12, 2011
  5. О чем пойдет речь? Что такое API Web API RESTful

    Web API REST vs RESTful Saturday, November 12, 2011
  6. REST Refresher REST - архитектурный стиль Что такое REST? Resources

    vs Representations (R & R) Richardson Maturity Model (RMM) Saturday, November 12, 2011
  7. Определение REST Client/Server Отсутствие контекста (Stateless) Единый Интерфейс (Uniform Interface)

    Кешируемость (Caching) Многоуровневая Система (Layered System) Код по запросу (Code on Demand) Saturday, November 12, 2011
  8. План создания Web API Определиться с R & R (Resources

    and their Representations) Детали использования HTTP протокола Security HTTP методы Обработка ошибок Коды состояния Ограничения запросов Кеширование Точки входа Saturday, November 12, 2011
  9. Доступные методы GET HEAD PUT POST DELETE PATCH Получение представления

    ресурса. Идентичен GET, без контента. Замена ресурса. Добавление (под-)ресурса. Удаление ресурса. Изменение ресурса. Saturday, November 12, 2011
  10. Коды состояния Метод On Success On Failure POST GET PATCH

    DELETE PUT 201  Created Location: 400  Bad  Request 200  OK 400  Bad  Request 404  Not  Found 200  OK 400  Bad  Request 404  Not  Found 204  No  Content 400  Bad  Request 404  Not  Found 410  Gone 204  No  Content 400  Bad  Request 404  Not  Found Saturday, November 12, 2011
  11. Прочие детали Точки входа Кеширование Обработка ошибок Ограничение количества запросов

    Кодировка символов Cross Origin Resource Sharing JSON-P Pagination Saturday, November 12, 2011
  12. API Security Authentication (Basic, Digest, HMAC, OAuth2) В production только

    SSL Тема для отдельного доклада Saturday, November 12, 2011
  13. Версионность API Зачем нужна версионность? Добавление версии в URI https://api.my.com/v3/customers/123

    Добавление параметра https://api.my.com/customers/123?v=3 Использование HTTP-заголовков ? Saturday, November 12, 2011
  14. Версия в URI Бэдсабачка :( Маладес :) https://api.my.com/v3.0/customer/123 ====> GET

     /v3.0/customer/123  HTTP/1.1 Accept:  application/json <==== HTTP/1.1  200  OK Content-­‐Type:  application/json {    "customer":  {          "version":  "0.3",          "name":  "Sasha  Beliy"    } } https://api.my.com/customer/123 ====> GET  /customer/123  HTTP/1.1 Accept:  application/vic.myapp-­‐v3+json <==== HTTP/1.1  200  OK Content-­‐Type:  application/vic.myapp-­‐v3+json {    "customer":  {          "name":  "Sasha  Beliy"    } } https://api.my.com/customer/123?format=xml ====> GET  /customer/123?format=xml  HTTP/1.1 https://api.my.com/customer/123 ====> GET  /customer/123  HTTP/1.1 Accept:  application/xml Saturday, November 12, 2011
  15. GitHub Gists API Version 3 of the API http://developer.github.com/v3/gists/ Рассматриваемые

    Методы: POST, GET, PATCH, DELETE, PUT Saturday, November 12, 2011
  16. User Entity class  User {        //  skip

           /**          *  @ORM\OneToMany(targetEntity="Gist",          *                                mappedBy="user")          */        protected  $gists;        //  skip } Saturday, November 12, 2011
  17. Gist Entity class  Gist {        //  skip

           /**          *  @ORM\ManyToOne(targetEntity="User",                                            inversedBy="gists")          */        protected  $user;                //  skip } Saturday, November 12, 2011
  18. Интерфейс List Get a single gist Create a gist Edit

    a gist Star/Unstar a gist Is a gist starred? Delete a gist GET  /gists GET  /gists/starred GET  /gists/:id POST  /gists PATCH  /gists/:id PUT  /gists/:id/star DELETE  /gists/:id/star GET  /gists/:id/star DELETE  /gists/:id Saturday, November 12, 2011
  19. Представление Формат Пример JSON 1  { 2      

       "id":  42, 3          "description":  "some  description", 4          "content":  "some  content" 5  } Saturday, November 12, 2011
  20. Представление RepresentationInterface --------------------------- - iterator + toString() JSONRepresentation UserIteratorAggregate GistIteratorAggregate

    XMLRepresentation FieldsIteratorAggregate ----------------------------- + getIterator() Saturday, November 12, 2011
  21. Setup Controller Action /**  *  GET  /gists/:id  */ public  function

     get($id) {        $gist  =  $this-­‐>getService()                                  -­‐>get($id);        $this-­‐>response-­‐>setStatusCode(200);        $repr  =  new  JsonRepresentation($gist);        return  array(                'content'  =>  $repr-­‐>toString()  );         } Saturday, November 12, 2011
  22. Entity Service public  function  get($id) {        $gist

     =  $this-­‐>em                                  -­‐>find('Gists\Entity\Gist',  $id);        if  ($gist)  {                $repr  =  new  GistIteratorAggregate($gist);        }        throw  NotFoundException('Not  Found'); } Saturday, November 12, 2011
  23. Setup Routing return  array(        'routes'  =>  array(

                   'gists'  =>  array(                        'type'        =>  'Zend\Mvc\Router\Http\Regex',                        'options'  =>  array(                        'regex'      =>                                            '/gists(/(?<id>[0-­‐9]*[^/]+)?)?',                                'defaults'  =>  array(                                        'controller'  =>  'gists_index',                                ),                        ),                ),        ), ); Saturday, November 12, 2011
  24. Unit Testing Кто не понимает зачем, того поздно спасать! Zend\Mvc\ModuleManager

    GistsTests\Framework\TestCase Тестируем: Сервисный слой Модели Saturday, November 12, 2011
  25. UTs Bootstrap use  GistsTest\Framework\TestCase; $moduleManager  =  new  \Zend\Module\Manager(array(    'SpiffyDoctrine',

     'Application',  'Gists') ); $moduleManager-­‐>loadModules(); $mergedConfig  =  $moduleManager    -­‐>getMergedConfig()    -­‐>toArray(); //  sets  up  (and  exposes):   //  service  locator,  entity  manager  etc TestCase::$config  =  $mergedConfig; Saturday, November 12, 2011
  26. Test Case Setup namespace  GistsTest; class  FooTest  extends  Framework\TestCase {

           protected  $service;        public  function  setUp()        {                parent::setup();        //  manners                $this-­‐>service  =  $this-­‐>getLocator()                                                            -­‐>get('api');        } Saturday, November 12, 2011
  27. Functional Testing /**  *  GET  /gists/:id/star  */ public  function  testIsGistStaredTrue()

    {        $result  =  $this-­‐>getCurl()-­‐>request(                'GET',  $gist-­‐>value  .  '/star'        );        $this-­‐>assertSame(                'HTTP/1.1  204  No  Content',                    $result['status']        ); } Saturday, November 12, 2011
  28. Load Testing Инструменты ab siege php + curl + loop

    Цель: Узнать точку слома, понять (roughly!) на что способен сервис в текущей конфигурации Saturday, November 12, 2011
  29. А вы знаете, что .. Жизнь очень упрощается если у

    вас есть: Мозги Понимание главенствующей парадигмы Модульные и (!) функциональные тесты Непрерывная интеграция Saturday, November 12, 2011