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

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

Dd3f18c87b851137000c7427d7bd5d32?s=47 fwdays
November 14, 2011

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

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

Dd3f18c87b851137000c7427d7bd5d32?s=128

fwdays

November 14, 2011
Tweet

More Decks by fwdays

Other Decks in Programming

Transcript

  1. ZF2 + API Создание легковесного API средствами ZF2 Saturday, November

    12, 2011
  2. Список литературы 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
  3. Об авторе ZF Hacker Phrozn (phrozn.info) Phing (phing.info) zftalk.dev (zf.rpod.ru)

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

    4. Тестирование 5. Поддержка Saturday, November 12, 2011
  5. 1. Потребность в API Saturday, November 12, 2011

  6. Плюсы создания API Developers, developers, developers, developers!! Более продуманная архитектура

    Доступность данных Превращение конкурентов в партнеров Saturday, November 12, 2011
  7. Небесплатный сыр Время и деньги Превоночальное создание Цена поддержки Холодный

    старт Saturday, November 12, 2011
  8. Decisions Выбор протокола Выбор формата данных Выбор каркаса разработки Saturday,

    November 12, 2011
  9. 2. Проектирование API Saturday, November 12, 2011

  10. О чем пойдет речь? Что такое API Web API RESTful

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

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

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

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

    Module User Gist Saturday, November 12, 2011
  15. Доступные методы GET HEAD PUT POST DELETE PATCH Получение представления

    ресурса. Идентичен GET, без контента. Замена ресурса. Добавление (под-)ресурса. Удаление ресурса. Изменение ресурса. Saturday, November 12, 2011
  16. Коды состояния Метод 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
  17. Прочие детали Точки входа Кеширование Обработка ошибок Ограничение количества запросов

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

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

    Добавление параметра https://api.my.com/customers/123?v=3 Использование HTTP-заголовков ? Saturday, November 12, 2011
  20. Версия в 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
  21. 3. Создание API Saturday, November 12, 2011

  22. GitHub Gists API Version 3 of the API http://developer.github.com/v3/gists/ Рассматриваемые

    Методы: POST, GET, PATCH, DELETE, PUT Saturday, November 12, 2011
  23. Базовые Компоненты Zend Framework 2 ZendSkeletonModule SpiffyDoctrine Gists (наш модуль)

    Doctrine 2 ORM Saturday, November 12, 2011
  24. Важные классы Zend\Mvc\Controller\RestfulController Gists\Mvc\Controller\RestfulController Application\Http\PhpEnvironment\Request Saturday, November 12, 2011

  25. Ресурсы    User -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐ id username gists Gist -­‐-­‐-­‐-­‐-­‐-­‐-­‐ id

    user description content Saturday, November 12, 2011
  26. User Entity class  User {        //  skip

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

           /**          *  @ORM\ManyToOne(targetEntity="User",                                            inversedBy="gists")          */        protected  $user;                //  skip } Saturday, November 12, 2011
  28. Интерфейс 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
  29. Представление Формат Пример JSON 1  { 2      

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

    XMLRepresentation FieldsIteratorAggregate ----------------------------- + getIterator() Saturday, November 12, 2011
  31. 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
  32. 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
  33. 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
  34. 4. Тестирование API Saturday, November 12, 2011

  35. Типы тестирования Ручками! Модульное Функциональное Нагрузочное и стресс тестирование Saturday,

    November 12, 2011
  36. Quick & Dirty CURL Браузер 3rd Party Tools (apigee.com) Saturday,

    November 12, 2011
  37. Unit Testing Кто не понимает зачем, того поздно спасать! Zend\Mvc\ModuleManager

    GistsTests\Framework\TestCase Тестируем: Сервисный слой Модели Saturday, November 12, 2011
  38. 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
  39. 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
  40. 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
  41. Load Testing Инструменты ab siege php + curl + loop

    Цель: Узнать точку слома, понять (roughly!) на что способен сервис в текущей конфигурации Saturday, November 12, 2011
  42. 5. Поддержка API Saturday, November 12, 2011

  43. А вы знаете, что .. Жизнь очень упрощается если у

    вас есть: Мозги Понимание главенствующей парадигмы Модульные и (!) функциональные тесты Непрерывная интеграция Saturday, November 12, 2011
  44. Extras/Closing Thoughts API Documentation Depricating Генераторы кода Never expose more

    than necessary Saturday, November 12, 2011
  45. Исчо! Fork the project (github.com/farazdagi/zf2-rest) Slice the project Help redefining

    the REST in ZF2 Saturday, November 12, 2011
  46. THE END @farazdagi Saturday, November 12, 2011