SlideShare une entreprise Scribd logo
1  sur  58
Télécharger pour lire hors ligne
Обработка сложных
POST/PATCH запросов в
     RESTful API
              Dmitry Petrov
      old.fightmaster@gmail.com
Product Fulfillment and Information Tracking




                         ProFIT
            Система управления
            производственными
         процессами типографии


                                               Dmitry Petrov
Product Fulfillment and Information Tracking




                         ProFIT
    Ежедневно:
    ~ 1 000 заказов
    ~1 000 000 печатной продукции
    1 час простоя ~ 25 000$

                                               Dmitry Petrov
RESTful API для ProFIT




              RESTful API

   ~ 60 entity
   ~100 API endpoints
   Сложная бизнес логика

                            Dmitry Petrov
RESTful API, примеры GET

   GET /api/orders/12                             GET /api/orders/12/items/fg45sf54
   Ответ сервера:                                 Ответ сервера:
   {                                              {
       "id": 12,                                      "id": "fg45sf54",
       "url": "http://localhost/api/orders/12",       "url": "http://localhost/api/orders/12/items/fg45sf54",
       "client": {                                    "product": "business cards",
           "firstname": "Dmitry",                     "quantity": 1000,
           "lastname": "Petrov",                      "previews": {
           "email": "",                                   "front": {
           "phone": null,                                      "large": "http://localhost/large/front.jpg",
           "address": {                                        "medium": "http://localhost/medium/front.jpg",
               "country": "Russia",                            "small": "http://localhost/small/front.jpg",
               "city": "Saratov",                         },
               "zip": 123456,                             "back": {
               "street": "Vavilova",                           "large": "http://localhost/large/back.jpg",
               "residentional": false                          "medium": "http://localhost/medium/back.jpg",
           }                                                   "small": "http://localhost/small/back.jpg",
       }                                                  }
   }                                                  }
                                                  }

                                                                                                          Dmitry Petrov
RESTful API, примеры GET

   GET /api/machines/KARAT+1/hot-folders   GET /api/product-box-types/12-type/associations
   Ответ сервера:                          Ответ сервера:
   [                                       [
       {                                       {
            "path":"/home/somepath/",               "id": 1,
            "types": [                              "product": "business_cards",
                "34-f-Type",                        "quantity": 1000
                "33-S-Type",                   },
                ......                         ......
            ]                              ]
       },
       ......
   ]


   GET /api/press-sheets/134/label
   Ответ сервера:
   {
       "label": "epl string"
   }


                                                                                   Dmitry Petrov
RESTful API, примеры POST / PUT

   POST http://localhost/api/orders,    POST http://localhost/api/press-sheets/12/transition
   PUT http://localhost/api/orders/12   Тело запроса:
   Тело запроса:                        {
   {                                        "transition": "start:printing:front",
       "id": 12,                            "note": null
       "client": {                      }
           "firstname": "Dmitry",
           "lastname": "Petrov",
           "email": "",
           "phone": null,
           "address": {
               "country": "Russia",
               "city": "Saratov",
               "zip": 123456,
               "street": "Vavilova",
               "residentional": false
           }
       }
   }


                                                                                    Dmitry Petrov
RESTful API, примеры PATCH

   Объект:                                         PATCH http://localhost/api/orders/12
   {                                               Тело запроса:
       "id": 12,                                   {
       "client": {                                     "client": {
           "firstname": "Dmitry",                           "email": "",
           "lastname": "Petrov",                            "phone": null
           "email": "old.fightmaster@gmail.com",       }
           "phone": "8-888-999",                   }
           "address": {                            PATCH http://localhost/api/orders/12
               "country": "Russia",                Тело запроса:
               "city": "Saratov",                  {
               "zip": 123456,                          "client": {
               "street": "Vavilova",                        "email": ""
               "residentional": false                  },
           }                                           "address": {
       }                                                    "street": "Vavilova",
   }                                                        "residentional": true
                                                       }
                                                   }


                                                                                          Dmitry Petrov
Призадумались . . .




                      Dmitry Petrov
Data Transfer Object




                           DTO
                                             DomainObject1

         DTO                                attribute1: String
                          Assembler
  attribute1: String
  attribute2: String   createDTO
                       updateDomainObject
  serialize
  deserialize
                                             DomainObject2

                                            attribute2: String




                                                                 Dmitry Petrov
Примеры DTO

  GET /api/orders/12
  Ответ сервера:
  {
      "id": 12,
      "url": "http://localhost/orders/12",
      "client": {
          "firstname": "Dmitry",
          "lastname": "Petrov",
          "email": "",
          "phone": null,
          "address": {
              "country": "Russia",
              "city": "Saratov",
              "zip": 123456,
              "street": "Vavilova",
              "residentional": false
          }
      }
  }


                                             Dmitry Petrov
Примеры DTO


 {
     "transition": "start:printing:front",
     "note": null
 }


 {
     "label": "epl string"
 }
 [
     {
          "path":"/home/somepath/",
          "types": [
              "34-f-Type",
              ......
          ]
     },
     ......
 ]


                                             Dmitry Petrov
Преимущества паттерна DTO




Уменьшение количества запросов
Независимость от API
"Заставляет думать"




                             Dmitry Petrov
Популярные бандлы и примеры




  FOSRestBundle
  JMSSerializerBundle
  LiipHelloBundle
  FOSCommentBundle


                              Dmitry Petrov
JMSSerializerBundle & GET метод


 GET /api/orders/12
 Ответ сервера:
 {
     "id": 12,
     "url": "http://localhost/api/orders/12",
     "client": {
         "firstname": "Dmitry",
         "lastname": "Petrov",
         "email": "",
         "phone": null,
         "address": {
             "country": "Russia",
             "city": "Saratov",
             "zip": 123456,
             "street": "Vavilova",
             "residentional": false
         }
     }
 }

                                                Dmitry Petrov
JMSSerializerBundle & POST метод


POST /api/orders,
Тело запроса:
{
    "id": 12,
    "client": {
        "firstname": "Dmitry",
        "lastname": "Petrov",
        "email": "",
        "phone": null,
        "address": {
            "country": "Russia",
            "city": "Saratov",
            "zip": 123456,
            "street": "Vavilova",
            "residentional": false
        }
    }
}


                                     Dmitry Petrov
JMSSerializerBundle & PATCH метод




                                    Dmitry Petrov
JMSSerializerBundle




  $this->deserialize($request, 'RestOrderDTO', 'json');




                                                   Dmitry Petrov
JMSSerializerBundle




                  MERGE


   $this->merge($oldDTO, $newDTO);



                                Dmitry Petrov
Сливание DTO




               Dmitry Petrov
JMSSerializerBundle & PATCH метод




PATCH /api/orders/12
Request:
{
    "client": {
        "email": "",
        "phone": null
    }
}




                                    Dmitry Petrov
RESTful API, JMSSerializerBundle



      Проблемы / Минусы

GET - сериализация null значений
PATCH - десериализация в объект
PATCH - merge null значений
MERGE - много бесполезного кода

                                   Dmitry Petrov
SimpleThingsFormSerializerBundle




 SimpleThingsFormSerializerBundle




                              15 июля 2012
                                        Dmitry Petrov
SimpleThingsFormSerializerBundle




                                   Dmitry Petrov
SimpleThingsFormSerializerBundle

GET /api/orders/12
Ответ сервера:
{
    "id": "12",
    "url": "http://localhost/orders/12",
    "client": {
        "firstname": "Dmitry",
        "lastname": "Petrov",
        "email": "",
        "phone": "",
        "address": {
            "country": "Russia",
            "city": "Saratov",
            "zip": "123456",
            "street": "Vavilova",
            "residentional": "false"
        }
    }
}


                                           Dmitry Petrov
SimpleThingsFormSerializerBundle




    Проблемы / Минусы

Конвертирование данных в string
Отсутствие поддержки PATCH (v. 2.0)
Идеологическая неприязнь
Грязная смесь *Type и *DTO
                                      Dmitry Petrov
Отпуск




         Dmitry Petrov
Отпуск




         Dmitry Petrov
Отпуск




         Dmitry Petrov
Изобретаем велосипед




            Требования

  (Де)Сериализация объектов
  Сохранение типа у данных
  Кеширование метаданных

                              Dmitry Petrov
Изобретаем велосипед




             Допущения

  Выходной формат json
  Метадата хранится в yml
  Всегда есть get/set методы

                               Dmitry Petrov
Изобретаем велосипед




        Через 36 часов...    поезд Саратов - Киев идет 30 часов




  SimpleSerializer
  SimpleSerializerBundle


  Подробности можно прочитать на хабре
                                                         Dmitry Petrov
SimpleSerializer




             Преимущества

Библиотека
Разделение правил сериализации от формата
Отсутствие озвученных минусов
"Интеллектуальная" десериализация


                                            Dmitry Petrov
SimpleSerializer & POST / PATCH




                                  Dmitry Petrov
SimpleSerializer & POST метод




                                Dmitry Petrov
RESTful API, валидация




        Что? Где? Когда?

   Параметры запросов
   Объекты передачи данных
   Бизнес-логика

                             Dmitry Petrov
RESTful API, валидация




    Параметры запросов


   /api/orders/12
   /api/boxes/BOX-1-1
   /api/orders?valid=true
                            Dmitry Petrov
RESTful API, валидация




     Routing requirements




                            Dmitry Petrov
RESTful API, валидация




        ParameterChecker




                           Dmitry Petrov
RESTful API, валидация




                         Dmitry Petrov
RESTful API, валидация




                         Dmitry Petrov
RESTful API, валидация


       AbstractRestController




                                Dmitry Petrov
RESTful API, валидация

                                                 PATCH /api/orders/12
 Объект:
                                                 Тело запроса:
 {
                                                 {
     "id": 12,
                                                     "client": {
     "client": {
                                                         "email": "",
         "firstname": "Dmitry",
                                                         "comment": "I'm hacker"
         "lastname": "Petrov",
                                                     }
         "email": "old.fightmaster@gmail.com",
                                                 }
         "phone": "8-888-999",
         "address": {
             "country": "Russia",
             "city": "Saratov",
             "zip": 123456,
             "street": "Vavilova",
             "residentional": false
         }
     }
 }




                                                                                   Dmitry Petrov
RESTful API, валидация


 Объект:                                     POST /api/press-sheets/12/transition
 {                                           Тело запроса:
     "transition": "start:printing:front",   {
     "note": null                                "transition": "start:printing:front",
 }                                               "note": null,
                                                 "comment": "I'm hacker"
                                             }
                                             POST /api/press-sheets/12/transition
                                             Тело запроса:
                                             {
                                                 "transition": "start:printing:front",
                                                 "comment": "I'm hacker"
                                             }




                                                                                         Dmitry Petrov
RESTful API, валидация




      Как, где и когда
      обрабатывать эти
      ситуации?


                         Dmitry Petrov
REST APIs with Symfony2: The Right Way




                                         Dmitry Petrov
REST APIs with Symfony2: The Right Way




                  Недостатки


 Рутиность
 Дублирование кода
 Работает лишь как фильтр
                                         Dmitry Petrov
SimpleSerializer




      "Интеллектуальная"
        десериализация
      3 режима десериализации:
   Strict, Medium strict, Non-strict
                         +
                   Поддержка групп
                                     Dmitry Petrov
RESTful API, обработка DTO




                             Dmitry Petrov
RESTful API, обработка объекта




                                 Dmitry Petrov
RESTful API, тестирование




           Behat, PHPUnit
   Контроллеры


   Data access layer
   Service layer
                            Dmitry Petrov
RESTful API, пример Behat сценария




                                     Dmitry Petrov
RESTful API, тестирование




              Проблемы

   Время выполнения:
   Behat ~ 90 минут
   PHPUnit ~ 5 минут

                            Dmitry Petrov
RESTful API, аутентификация




                      WSSE


Atom Authentication
How to create a custom Authentication Provider
EscapeWSSEAuthenticationBundle (v. 2.0)
MopaWSSEAuthenticationBundle (v. 2.1)

                                                 Dmitry Petrov
RESTful API, аутентификация




              WSSE Header

  X-WSSE: UsernameToken Username="bob",

  PasswordDigest="quR/EWLAV4xLf9Zqyw4pDmfV9OY=",

  Nonce="d36e316282959a9ed4c89851497a717f",

  Created="2003-12-15T14:43:07Z"




                                                   Dmitry Petrov
RESTful API, аутентификация




           Password digest


    Base64 (SHA1 (Nonce + CreationTimestamp + Password))




                                                      Dmitry Petrov
RESTful API, The End




                       Dmitry Petrov
RESTful API




                 Вопросы?
              @old_fightmaster




              https://github.com/opensoft
              https://github.com/fightmaster

                                    Отдельное спасибо команде ProFIT

                                                           Dmitry Petrov

Contenu connexe

Similaire à Обработка сложных POST/PATCH запросов в RESTful API

Rambler.iOS #8: Как не стать жертвой бэкендеров
Rambler.iOS #8: Как не стать жертвой бэкендеровRambler.iOS #8: Как не стать жертвой бэкендеров
Rambler.iOS #8: Как не стать жертвой бэкендеровRAMBLER&Co
 
«Пиринговый веб на JavaScript», Денис Глазков
«Пиринговый веб на JavaScript», Денис Глазков«Пиринговый веб на JavaScript», Денис Глазков
«Пиринговый веб на JavaScript», Денис ГлазковMail.ru Group
 
«Пиринговый веб на JavaScript», Денис Глазков, MoscowJS 28
«Пиринговый веб на JavaScript», Денис Глазков, MoscowJS 28«Пиринговый веб на JavaScript», Денис Глазков, MoscowJS 28
«Пиринговый веб на JavaScript», Денис Глазков, MoscowJS 28MoscowJS
 
Полуавтоматизация third-party API
Полуавтоматизация third-party APIПолуавтоматизация third-party API
Полуавтоматизация third-party APISQALab
 
Anton Shabouta "Implementing async binary clients in pure PHP"
Anton Shabouta "Implementing async binary clients in pure PHP" Anton Shabouta "Implementing async binary clients in pure PHP"
Anton Shabouta "Implementing async binary clients in pure PHP" Fwdays
 
Web осень 2012 лекция 4
Web осень 2012 лекция 4Web осень 2012 лекция 4
Web осень 2012 лекция 4Technopark
 
REST и HATEOAS
REST и HATEOASREST и HATEOAS
REST и HATEOASArtem Bey
 
"Пиринговый веб на JavaScript"
"Пиринговый веб на JavaScript""Пиринговый веб на JavaScript"
"Пиринговый веб на JavaScript"FDConf
 

Similaire à Обработка сложных POST/PATCH запросов в RESTful API (10)

Rambler.iOS #8: Как не стать жертвой бэкендеров
Rambler.iOS #8: Как не стать жертвой бэкендеровRambler.iOS #8: Как не стать жертвой бэкендеров
Rambler.iOS #8: Как не стать жертвой бэкендеров
 
«Пиринговый веб на JavaScript», Денис Глазков
«Пиринговый веб на JavaScript», Денис Глазков«Пиринговый веб на JavaScript», Денис Глазков
«Пиринговый веб на JavaScript», Денис Глазков
 
«Пиринговый веб на JavaScript», Денис Глазков, MoscowJS 28
«Пиринговый веб на JavaScript», Денис Глазков, MoscowJS 28«Пиринговый веб на JavaScript», Денис Глазков, MoscowJS 28
«Пиринговый веб на JavaScript», Денис Глазков, MoscowJS 28
 
Полуавтоматизация third-party API
Полуавтоматизация third-party APIПолуавтоматизация third-party API
Полуавтоматизация third-party API
 
Anton Shabouta "Implementing async binary clients in pure PHP"
Anton Shabouta "Implementing async binary clients in pure PHP" Anton Shabouta "Implementing async binary clients in pure PHP"
Anton Shabouta "Implementing async binary clients in pure PHP"
 
Web осень 2012 лекция 4
Web осень 2012 лекция 4Web осень 2012 лекция 4
Web осень 2012 лекция 4
 
REST и HATEOAS
REST и HATEOASREST и HATEOAS
REST и HATEOAS
 
Target.Mail.Ru API v2
Target.Mail.Ru API v2Target.Mail.Ru API v2
Target.Mail.Ru API v2
 
Target mail.ru API v2
Target mail.ru API v2Target mail.ru API v2
Target mail.ru API v2
 
"Пиринговый веб на JavaScript"
"Пиринговый веб на JavaScript""Пиринговый веб на JavaScript"
"Пиринговый веб на JavaScript"
 

Обработка сложных POST/PATCH запросов в RESTful API

  • 1. Обработка сложных POST/PATCH запросов в RESTful API Dmitry Petrov old.fightmaster@gmail.com
  • 2. Product Fulfillment and Information Tracking ProFIT Система управления производственными процессами типографии Dmitry Petrov
  • 3. Product Fulfillment and Information Tracking ProFIT Ежедневно: ~ 1 000 заказов ~1 000 000 печатной продукции 1 час простоя ~ 25 000$ Dmitry Petrov
  • 4. RESTful API для ProFIT RESTful API ~ 60 entity ~100 API endpoints Сложная бизнес логика Dmitry Petrov
  • 5. RESTful API, примеры GET GET /api/orders/12 GET /api/orders/12/items/fg45sf54 Ответ сервера: Ответ сервера: { { "id": 12, "id": "fg45sf54", "url": "http://localhost/api/orders/12", "url": "http://localhost/api/orders/12/items/fg45sf54", "client": { "product": "business cards", "firstname": "Dmitry", "quantity": 1000, "lastname": "Petrov", "previews": { "email": "", "front": { "phone": null, "large": "http://localhost/large/front.jpg", "address": { "medium": "http://localhost/medium/front.jpg", "country": "Russia", "small": "http://localhost/small/front.jpg", "city": "Saratov", }, "zip": 123456, "back": { "street": "Vavilova", "large": "http://localhost/large/back.jpg", "residentional": false "medium": "http://localhost/medium/back.jpg", } "small": "http://localhost/small/back.jpg", } } } } } Dmitry Petrov
  • 6. RESTful API, примеры GET GET /api/machines/KARAT+1/hot-folders GET /api/product-box-types/12-type/associations Ответ сервера: Ответ сервера: [ [ { { "path":"/home/somepath/", "id": 1, "types": [ "product": "business_cards", "34-f-Type", "quantity": 1000 "33-S-Type", }, ...... ...... ] ] }, ...... ] GET /api/press-sheets/134/label Ответ сервера: { "label": "epl string" } Dmitry Petrov
  • 7. RESTful API, примеры POST / PUT POST http://localhost/api/orders, POST http://localhost/api/press-sheets/12/transition PUT http://localhost/api/orders/12 Тело запроса: Тело запроса: { { "transition": "start:printing:front", "id": 12, "note": null "client": { } "firstname": "Dmitry", "lastname": "Petrov", "email": "", "phone": null, "address": { "country": "Russia", "city": "Saratov", "zip": 123456, "street": "Vavilova", "residentional": false } } } Dmitry Petrov
  • 8. RESTful API, примеры PATCH Объект: PATCH http://localhost/api/orders/12 { Тело запроса: "id": 12, { "client": { "client": { "firstname": "Dmitry", "email": "", "lastname": "Petrov", "phone": null "email": "old.fightmaster@gmail.com", } "phone": "8-888-999", } "address": { PATCH http://localhost/api/orders/12 "country": "Russia", Тело запроса: "city": "Saratov", { "zip": 123456, "client": { "street": "Vavilova", "email": "" "residentional": false }, } "address": { } "street": "Vavilova", } "residentional": true } } Dmitry Petrov
  • 10. Data Transfer Object DTO DomainObject1 DTO attribute1: String Assembler attribute1: String attribute2: String createDTO updateDomainObject serialize deserialize DomainObject2 attribute2: String Dmitry Petrov
  • 11. Примеры DTO GET /api/orders/12 Ответ сервера: { "id": 12, "url": "http://localhost/orders/12", "client": { "firstname": "Dmitry", "lastname": "Petrov", "email": "", "phone": null, "address": { "country": "Russia", "city": "Saratov", "zip": 123456, "street": "Vavilova", "residentional": false } } } Dmitry Petrov
  • 12. Примеры DTO { "transition": "start:printing:front", "note": null } { "label": "epl string" } [ { "path":"/home/somepath/", "types": [ "34-f-Type", ...... ] }, ...... ] Dmitry Petrov
  • 13. Преимущества паттерна DTO Уменьшение количества запросов Независимость от API "Заставляет думать" Dmitry Petrov
  • 14. Популярные бандлы и примеры FOSRestBundle JMSSerializerBundle LiipHelloBundle FOSCommentBundle Dmitry Petrov
  • 15. JMSSerializerBundle & GET метод GET /api/orders/12 Ответ сервера: { "id": 12, "url": "http://localhost/api/orders/12", "client": { "firstname": "Dmitry", "lastname": "Petrov", "email": "", "phone": null, "address": { "country": "Russia", "city": "Saratov", "zip": 123456, "street": "Vavilova", "residentional": false } } } Dmitry Petrov
  • 16. JMSSerializerBundle & POST метод POST /api/orders, Тело запроса: { "id": 12, "client": { "firstname": "Dmitry", "lastname": "Petrov", "email": "", "phone": null, "address": { "country": "Russia", "city": "Saratov", "zip": 123456, "street": "Vavilova", "residentional": false } } } Dmitry Petrov
  • 17. JMSSerializerBundle & PATCH метод Dmitry Petrov
  • 18. JMSSerializerBundle $this->deserialize($request, 'RestOrderDTO', 'json'); Dmitry Petrov
  • 19. JMSSerializerBundle MERGE $this->merge($oldDTO, $newDTO); Dmitry Petrov
  • 20. Сливание DTO Dmitry Petrov
  • 21. JMSSerializerBundle & PATCH метод PATCH /api/orders/12 Request: { "client": { "email": "", "phone": null } } Dmitry Petrov
  • 22. RESTful API, JMSSerializerBundle Проблемы / Минусы GET - сериализация null значений PATCH - десериализация в объект PATCH - merge null значений MERGE - много бесполезного кода Dmitry Petrov
  • 25. SimpleThingsFormSerializerBundle GET /api/orders/12 Ответ сервера: { "id": "12", "url": "http://localhost/orders/12", "client": { "firstname": "Dmitry", "lastname": "Petrov", "email": "", "phone": "", "address": { "country": "Russia", "city": "Saratov", "zip": "123456", "street": "Vavilova", "residentional": "false" } } } Dmitry Petrov
  • 26. SimpleThingsFormSerializerBundle Проблемы / Минусы Конвертирование данных в string Отсутствие поддержки PATCH (v. 2.0) Идеологическая неприязнь Грязная смесь *Type и *DTO Dmitry Petrov
  • 27. Отпуск Dmitry Petrov
  • 28. Отпуск Dmitry Petrov
  • 29. Отпуск Dmitry Petrov
  • 30. Изобретаем велосипед Требования (Де)Сериализация объектов Сохранение типа у данных Кеширование метаданных Dmitry Petrov
  • 31. Изобретаем велосипед Допущения Выходной формат json Метадата хранится в yml Всегда есть get/set методы Dmitry Petrov
  • 32. Изобретаем велосипед Через 36 часов... поезд Саратов - Киев идет 30 часов SimpleSerializer SimpleSerializerBundle Подробности можно прочитать на хабре Dmitry Petrov
  • 33. SimpleSerializer Преимущества Библиотека Разделение правил сериализации от формата Отсутствие озвученных минусов "Интеллектуальная" десериализация Dmitry Petrov
  • 34. SimpleSerializer & POST / PATCH Dmitry Petrov
  • 35. SimpleSerializer & POST метод Dmitry Petrov
  • 36. RESTful API, валидация Что? Где? Когда? Параметры запросов Объекты передачи данных Бизнес-логика Dmitry Petrov
  • 37. RESTful API, валидация Параметры запросов /api/orders/12 /api/boxes/BOX-1-1 /api/orders?valid=true Dmitry Petrov
  • 38. RESTful API, валидация Routing requirements Dmitry Petrov
  • 39. RESTful API, валидация ParameterChecker Dmitry Petrov
  • 42. RESTful API, валидация AbstractRestController Dmitry Petrov
  • 43. RESTful API, валидация PATCH /api/orders/12 Объект: Тело запроса: { { "id": 12, "client": { "client": { "email": "", "firstname": "Dmitry", "comment": "I'm hacker" "lastname": "Petrov", } "email": "old.fightmaster@gmail.com", } "phone": "8-888-999", "address": { "country": "Russia", "city": "Saratov", "zip": 123456, "street": "Vavilova", "residentional": false } } } Dmitry Petrov
  • 44. RESTful API, валидация Объект: POST /api/press-sheets/12/transition { Тело запроса: "transition": "start:printing:front", { "note": null "transition": "start:printing:front", } "note": null, "comment": "I'm hacker" } POST /api/press-sheets/12/transition Тело запроса: { "transition": "start:printing:front", "comment": "I'm hacker" } Dmitry Petrov
  • 45. RESTful API, валидация Как, где и когда обрабатывать эти ситуации? Dmitry Petrov
  • 46. REST APIs with Symfony2: The Right Way Dmitry Petrov
  • 47. REST APIs with Symfony2: The Right Way Недостатки Рутиность Дублирование кода Работает лишь как фильтр Dmitry Petrov
  • 48. SimpleSerializer "Интеллектуальная" десериализация 3 режима десериализации: Strict, Medium strict, Non-strict + Поддержка групп Dmitry Petrov
  • 49. RESTful API, обработка DTO Dmitry Petrov
  • 50. RESTful API, обработка объекта Dmitry Petrov
  • 51. RESTful API, тестирование Behat, PHPUnit Контроллеры Data access layer Service layer Dmitry Petrov
  • 52. RESTful API, пример Behat сценария Dmitry Petrov
  • 53. RESTful API, тестирование Проблемы Время выполнения: Behat ~ 90 минут PHPUnit ~ 5 минут Dmitry Petrov
  • 54. RESTful API, аутентификация WSSE Atom Authentication How to create a custom Authentication Provider EscapeWSSEAuthenticationBundle (v. 2.0) MopaWSSEAuthenticationBundle (v. 2.1) Dmitry Petrov
  • 55. RESTful API, аутентификация WSSE Header X-WSSE: UsernameToken Username="bob", PasswordDigest="quR/EWLAV4xLf9Zqyw4pDmfV9OY=", Nonce="d36e316282959a9ed4c89851497a717f", Created="2003-12-15T14:43:07Z" Dmitry Petrov
  • 56. RESTful API, аутентификация Password digest Base64 (SHA1 (Nonce + CreationTimestamp + Password)) Dmitry Petrov
  • 57. RESTful API, The End Dmitry Petrov
  • 58. RESTful API Вопросы? @old_fightmaster https://github.com/opensoft https://github.com/fightmaster Отдельное спасибо команде ProFIT Dmitry Petrov