Your SlideShare is downloading. ×
  • Like
Обработка сложных POST/PATCH запросов в RESTful API
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Now you can save presentations on your phone or tablet

Available for both IPhone and Android

Text the download link to your phone

Standard text messaging rates apply

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

  • 783 views
Published

Доклад с sfcampua 2012

Доклад с sfcampua 2012

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
783
On SlideShare
0
From Embeds
0
Number of Embeds
2

Actions

Shares
Downloads
6
Comments
0
Likes
2

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 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
  • 9. Призадумались . . . 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/12Request:{ "client": { "email": "", "phone": null }} Dmitry Petrov
  • 22. RESTful API, JMSSerializerBundle Проблемы / МинусыGET - сериализация null значенийPATCH - десериализация в объектPATCH - merge null значенийMERGE - много бесполезного кода Dmitry Petrov
  • 23. SimpleThingsFormSerializerBundle SimpleThingsFormSerializerBundle 15 июля 2012 Dmitry Petrov
  • 24. SimpleThingsFormSerializerBundle Dmitry Petrov
  • 25. SimpleThingsFormSerializerBundleGET /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
  • 40. RESTful API, валидация Dmitry Petrov
  • 41. RESTful API, валидация Dmitry Petrov
  • 42. RESTful API, валидация AbstractRestController Dmitry Petrov
  • 43. RESTful API, валидация PATCH /api/orders/12 Объект: Тело запроса: { { "id": 12, "client": { "client": { "email": "", "firstname": "Dmitry", "comment": "Im 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": "Im hacker" } POST /api/press-sheets/12/transition Тело запроса: { "transition": "start:printing:front", "comment": "Im 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, аутентификация WSSEAtom AuthenticationHow to create a custom Authentication ProviderEscapeWSSEAuthenticationBundle (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