Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Обработка сложных POST/PATCH запросов в RESTfu API
Search
Dmitry Petrov
December 03, 2012
560
1
Share
Обработка сложных POST/PATCH запросов в RESTfu API
Доклад с выступления на sfcampua 2012
Dmitry Petrov
December 03, 2012
More Decks by Dmitry Petrov
See All by Dmitry Petrov
Handle complex POST/PATCH requests in RESTful API
fightmaster
1
190
Featured
See All Featured
GraphQLとの向き合い方2022年版
quramy
50
15k
Odyssey Design
rkendrick25
PRO
2
620
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
0
230
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2k
Docker and Python
trallard
47
3.8k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
150
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
700
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
250
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
231
23k
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
61
44k
Evolving SEO for Evolving Search Engines
ryanjones
0
200
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9k
Transcript
Dmitry Petrov
[email protected]
Обработка сложных POST/PATCH запросов в RESTful API
ProFIT Dmitry Petrov Система управления производственными процессами типографии Product Fulfillment
and Information Tracking
ProFIT Dmitry Petrov Ежедневно: ~ 1 000 заказов ~1 000
000 печатной продукции 1 час простоя ~ 25 000$ Product Fulfillment and Information Tracking
RESTful API Dmitry Petrov ~ 60 entity ~100 API endpoints
Сложная бизнес логика RESTful API для ProFIT
Dmitry Petrov GET /api/orders/12/items/fg45sf54 Ответ сервера: { "id": "fg45sf54", "url":
"http://localhost/api/orders/12/items/fg45sf54", "product": "business cards", "quantity": 1000, "previews": { "front": { "large": "http://localhost/large/front.jpg", "medium": "http://localhost/medium/front.jpg", "small": "http://localhost/small/front.jpg", }, "back": { "large": "http://localhost/large/back.jpg", "medium": "http://localhost/medium/back.jpg", "small": "http://localhost/small/back.jpg", } } } 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 } } } RESTful API, примеры GET
Dmitry Petrov GET /api/product-box-types/12-type/associations Ответ сервера: [ { "id": 1,
"product": "business_cards", "quantity": 1000 }, ...... ] GET /api/machines/KARAT+1/hot-folders Ответ сервера: [ { "path":"/home/somepath/", "types": [ "34-f-Type", "33-S-Type", ...... ] }, ...... ] GET /api/press-sheets/134/label Ответ сервера: { "label": "epl string" } RESTful API, примеры GET
Dmitry Petrov POST http://localhost/api/press-sheets/12/transition Тело запроса: { "transition": "start:printing:front", "note":
null } POST http://localhost/api/orders, PUT http://localhost/api/orders/12 Тело запроса: { "id": 12, "client": { "firstname": "Dmitry", "lastname": "Petrov", "email": "", "phone": null, "address": { "country": "Russia", "city": "Saratov", "zip": 123456, "street": "Vavilova", "residentional": false } } } RESTful API, примеры POST / PUT
Dmitry Petrov PATCH http://localhost/api/orders/12 Тело запроса: { "client": { "email":
"", "phone": null } } PATCH http://localhost/api/orders/12 Тело запроса: { "client": { "email": "" }, "address": { "street": "Vavilova", "residentional": true } } Объект: { "id": 12, "client": { "firstname": "Dmitry", "lastname": "Petrov", "email": "
[email protected]
", "phone": "8-888-999", "address": { "country": "Russia", "city": "Saratov", "zip": 123456, "street": "Vavilova", "residentional": false } } } RESTful API, примеры PATCH
Dmitry Petrov Призадумались . . .
DTO Dmitry Petrov Data Transfer Object DTO attribute1: String attribute2:
String Assembler createDTO updateDomainObject serialize deserialize DomainObject1 attribute1: String DomainObject2 attribute2: String
Dmitry Petrov 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 } } } Примеры DTO
Dmitry Petrov { "transition": "start:printing:front", "note": null } { "label":
"epl string" } [ { "path":"/home/somepath/", "types": [ "34-f-Type", ...... ] }, ...... ] Примеры DTO
Dmitry Petrov Уменьшение количества запросов Независимость от API "Заставляет думать"
Преимущества паттерна DTO
Dmitry Petrov FOSRestBundle JMSSerializerBundle LiipHelloBundle FOSCommentBundle Популярные бандлы и примеры
Dmitry Petrov 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 } } } JMSSerializerBundle & GET метод
Dmitry Petrov POST /api/orders, Тело запроса: { "id": 12, "client":
{ "firstname": "Dmitry", "lastname": "Petrov", "email": "", "phone": null, "address": { "country": "Russia", "city": "Saratov", "zip": 123456, "street": "Vavilova", "residentional": false } } } JMSSerializerBundle & POST метод
Dmitry Petrov JMSSerializerBundle & PATCH метод
Dmitry Petrov $this->deserialize($request, 'Rest\OrderDTO', 'json'); JMSSerializerBundle
MERGE Dmitry Petrov $this->merge($oldDTO, $newDTO); JMSSerializerBundle
Dmitry Petrov Сливание DTO
Dmitry Petrov PATCH /api/orders/12 Request: { "client": { "email": "",
"phone": null } } JMSSerializerBundle & PATCH метод
Проблемы / Минусы Dmitry Petrov GET - сериализация null значений
PATCH - десериализация в объект PATCH - merge null значений MERGE - много бесполезного кода RESTful API, JMSSerializerBundle
Dmitry Petrov SimpleThingsFormSerializerBundle 15 июля 2012 SimpleThingsFormSerializerBundle
Dmitry Petrov SimpleThingsFormSerializerBundle
Dmitry Petrov 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" } } } SimpleThingsFormSerializerBundle
Проблемы / Минусы Dmitry Petrov Конвертирование данных в string Отсутствие
поддержки PATCH (v. 2.0) Идеологическая неприязнь Грязная смесь *Type и *DTO SimpleThingsFormSerializerBundle
Dmitry Petrov Отпуск
Dmitry Petrov Отпуск
Dmitry Petrov Отпуск
Требования Dmitry Petrov (Де)Сериализация объектов Сохранение типа у данных Кеширование
метаданных Изобретаем велосипед
Допущения Dmitry Petrov Выходной формат json Метадата хранится в yml
Всегда есть get/set методы Изобретаем велосипед
Через 36 часов... поезд Саратов - Киев идет 30 часов
Dmitry Petrov SimpleSerializer SimpleSerializerBundle Подробности можно прочитать на хабре Изобретаем велосипед
Преимущества Dmitry Petrov Библиотека Разделение правил сериализации от формата Отсутствие
озвученных минусов "Интеллектуальная" десериализация SimpleSerializer
Dmitry Petrov SimpleSerializer & POST / PATCH
Dmitry Petrov SimpleSerializer & POST метод
Что? Где? Когда? Dmitry Petrov Параметры запросов Объекты передачи данных
Бизнес-логика RESTful API, валидация
Параметры запросов Dmitry Petrov /api/orders/12 /api/boxes/BOX-1-1 /api/orders?valid=true RESTful API, валидация
Routing requirements Dmitry Petrov RESTful API, валидация
Dmitry Petrov ParameterChecker RESTful API, валидация
Dmitry Petrov RESTful API, валидация
Dmitry Petrov RESTful API, валидация
Dmitry Petrov AbstractRestController RESTful API, валидация
Dmitry Petrov PATCH /api/orders/12 Тело запроса: { "client": { "email":
"", "comment": "I'm hacker" } } Объект: { "id": 12, "client": { "firstname": "Dmitry", "lastname": "Petrov", "email": "
[email protected]
", "phone": "8-888-999", "address": { "country": "Russia", "city": "Saratov", "zip": 123456, "street": "Vavilova", "residentional": false } } } RESTful API, валидация
Dmitry Petrov POST /api/press-sheets/12/transition Тело запроса: { "transition": "start:printing:front", "note":
null, "comment": "I'm hacker" } POST /api/press-sheets/12/transition Тело запроса: { "transition": "start:printing:front", "comment": "I'm hacker" } Объект: { "transition": "start:printing:front", "note": null } RESTful API, валидация
Dmitry Petrov Как, где и когда обрабатывать эти ситуации? RESTful
API, валидация
Dmitry Petrov REST APIs with Symfony2: The Right Way
Dmitry Petrov Недостатки Рутиность Дублирование кода Работает лишь как фильтр
REST APIs with Symfony2: The Right Way
Dmitry Petrov "Интеллектуальная" десериализация 3 режима десериализации: Strict, Medium strict,
Non-strict + Поддержка групп SimpleSerializer
Dmitry Petrov RESTful API, обработка DTO
Dmitry Petrov RESTful API, обработка объекта
Behat, PHPUnit Dmitry Petrov Контроллеры Data access layer Service layer
RESTful API, тестирование
Dmitry Petrov RESTful API, пример Behat сценария
Проблемы Dmitry Petrov Время выполнения: Behat ~ 90 минут PHPUnit
~ 5 минут RESTful API, тестирование
WSSE Dmitry Petrov Atom Authentication How to create a custom
Authentication Provider EscapeWSSEAuthenticationBundle (v. 2.0) MopaWSSEAuthenticationBundle (v. 2.1) RESTful API, аутентификация
WSSE Header Dmitry Petrov X-WSSE: UsernameToken Username="bob", PasswordDigest="quR/EWLAV4xLf9Zqyw4pDmfV9OY=", Nonce="d36e316282959a9ed4c89851497a717f", Created="2003-12-15T14:43:07Z"
RESTful API, аутентификация
Password digest Dmitry Petrov Base64 (SHA1 (Nonce + CreationTimestamp +
Password)) RESTful API, аутентификация
Dmitry Petrov RESTful API, The End
Вопросы? Dmitry Petrov @old_fightmaster RESTful API https://github.com/opensoft https://github.com/fightmaster Отдельное спасибо
команде ProFIT