Handle ComplexPOST/PATCH requests in     RESTful API              Dmitry Petrov      old.fightmaster@gmail.com
Product Fulfillment and Information Tracking                         ProFIT            The system of process              ...
Product Fulfillment and Information Tracking                         ProFIT    Daily:    ~ 1 000 orders    ~1 000 000 prin...
RESTful API for ProFIT               RESTful API   ~ 60 entity   ~100 API endpoints   Complex business logic              ...
RESTful API, examples GET   GET /api/orders/12                             GET /api/orders/12/items/fg45sf54   The server ...
RESTful API, examples GET   GET /api/machines/KARAT+1/hot-folders   GET /api/product-box-types/12-type/associations   The ...
RESTful API, examples POST / PUT   POST http://localhost/api/orders,    POST http://localhost/api/press-sheets/12/transiti...
RESTful API, examples PATCH   Object:                                         PATCH http://localhost/api/orders/12   {    ...
Become thoughtful . . .                          Dmitry Petrov
Data Transfer Object                           DTO                                             DomainObject1         DTO  ...
Examples of DTO   GET /api/orders/12   The server response:   {       "id": 12,       "url": "http://localhost/orders/12",...
Examples of DTO {     "transition": "start:printing:front",     "note": null } {     "label": "epl string" } [     {      ...
The benefits of using DTO patternReducing the number of queriesIndependence from API"Makes you think"                     ...
Popular bundles and examples   FOSRestBundle   JMSSerializerBundle   LiipHelloBundle   FOSCommentBundle                   ...
JMSSerializerBundle & GET method GET /api/orders/12 The server response: {     "id": 12,     "url": "http://localhost/api/...
JMSSerializerBundle & POST methodPOST /api/orders,Body of the request:{    "id": 12,    "client": {        "firstname": "D...
JMSSerializerBundle & PATCH method                                     Dmitry Petrov
JMSSerializerBundle  $this->deserialize($request, RestOrderDTO, json);                                                   D...
JMSSerializerBundle                  MERGE   $this->merge($oldDTO, $newDTO);                                Dmitry Petrov
Merging DTO              Dmitry Petrov
JMSSerializerBundle & PATCH methodPATCH /api/orders/12Request:{    "client": {        "email": "",        "phone": null   ...
RESTful API, JMSSerializerBundle Problems / DisadvantagesGET - serialization of null valuesPATCH - deserialized into an ob...
SimpleThingsFormSerializerBundle SimpleThingsFormSerializerBundle                               July 15, 2012             ...
SimpleThingsFormSerializerBundle                                   Dmitry Petrov
SimpleThingsFormSerializerBundleGET /api/orders/12The server response:{    "id": "12",    "url": "http://localhost/orders/...
SimpleThingsFormSerializerBundle Problems / DisadvantagesConverting data into stringLack of support PATCH method (v. 2.0)T...
Отпуск         Dmitry Petrov
Отпуск         Dmitry Petrov
Отпуск         Dmitry Petrov
Reinvent the wheel             Requirements   (Un)Serialization of objects   Preservation of the type in data   Metadata c...
Reinvent the wheel             Assumptions   The output format is json   Metadata is stored in yml   There are get/set met...
Reinvent the wheel            After 36 hours...   train Saratov - Kiev is comming 30 hours   SimpleSerializer   SimpleSeri...
SimpleSerializer                     BenefitsThis is librarySeparation of serialization rules and formatAbsence voiced dis...
SimpleSerializer & POST / PATCH                                  Dmitry Petrov
SimpleSerializer & POST method                                 Dmitry Petrov
RESTful API, validation     What? Where? When?   Parameters of requests   Data transfer objects   Business logic          ...
RESTful API, validation    Parameters of requests   /api/orders/12   /api/boxes/BOX-1-1   /api/orders?valid=true          ...
RESTful API, validation      Routing requirements                             Dmitry Petrov
RESTful API, validation         ParameterChecker                            Dmitry Petrov
RESTful API, validation                          Dmitry Petrov
RESTful API, validation                          Dmitry Petrov
RESTful API, validation        AbstractRestController                                 Dmitry Petrov
RESTful API, validation                                                 PATCH /api/orders/12 Object:                      ...
RESTful API, validation Object:                                     POST /api/press-sheets/12/transition {                ...
RESTful API, validation      How, where and      when to handle      these situations?                          Dmitry Pet...
REST APIs with Symfony2: The Right Way                                         Dmitry Petrov
REST APIs with Symfony2: The Right Way              Disadvantages Conventionalism Duplication of code Only works as filter...
SimpleSerializer                "Inteligent"               deserialization       3 modes of deserialization:   Strict, Med...
RESTful API, handle of DTO                             Dmitry Petrov
RESTful API, handle of domain object                                       Dmitry Petrov
RESTful API, testing            Behat, PHPUnit   Controllers   Data access layer   Service layer                          ...
RESTful API, Behat scenario                              Dmitry Petrov
RESTful API, testing                  Problems   Run time:   Behat ~ 90 minutes   PHPUnit ~ 5 minutes                     ...
RESTful API, authentication                      WSSEAtom AuthenticationHow to create a custom Authentication ProviderEsca...
RESTful API, authentication              WSSE Header  X-WSSE: UsernameToken Username="bob",  PasswordDigest="quR/EWLAV4xLf...
RESTful API, authentication           Password digest    Base64 (SHA1 (Nonce + CreationTimestamp + Password))             ...
RESTful API, The End                       Dmitry Petrov
RESTful API          Any questions?              @old_fightmaster              https://github.com/opensoft              ht...
Upcoming SlideShare
Loading in...5
×

Handle complex POST/PATCH requests in RESTful API

7,816

Published on

Report with a speech on the 2012 sfcampua

0 Comments
7 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
7,816
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
30
Comments
0
Likes
7
Embeds 0
No embeds

No notes for slide

Handle complex POST/PATCH requests in RESTful API

  1. 1. Handle ComplexPOST/PATCH requests in RESTful API Dmitry Petrov old.fightmaster@gmail.com
  2. 2. Product Fulfillment and Information Tracking ProFIT The system of process control printing Dmitry Petrov
  3. 3. Product Fulfillment and Information Tracking ProFIT Daily: ~ 1 000 orders ~1 000 000 print productions 1 hour of downtime ~ 25 000$ Dmitry Petrov
  4. 4. RESTful API for ProFIT RESTful API ~ 60 entity ~100 API endpoints Complex business logic Dmitry Petrov
  5. 5. RESTful API, examples GET GET /api/orders/12 GET /api/orders/12/items/fg45sf54 The server response: The server response: { { "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. 6. RESTful API, examples GET GET /api/machines/KARAT+1/hot-folders GET /api/product-box-types/12-type/associations The server response: The server response: [ [ { { "path":"/home/somepath/", "id": 1, "types": [ "product": "business_cards", "34-f-Type", "quantity": 1000 "33-S-Type", }, ...... ...... ] ] }, ...... ] GET /api/press-sheets/134/label The server response: { "label": "epl string" } Dmitry Petrov
  7. 7. RESTful API, examples POST / PUT POST http://localhost/api/orders, POST http://localhost/api/press-sheets/12/transition PUT http://localhost/api/orders/12 Body of the request: Body of the request: { { "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. 8. RESTful API, examples PATCH Object: PATCH http://localhost/api/orders/12 { Body of the request: "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", Body of the request: "city": "Saratov", { "zip": 123456, "client": { "street": "Vavilova", "email": "" "residentional": false }, } "address": { } "street": "Vavilova", } "residentional": true } } Dmitry Petrov
  9. 9. Become thoughtful . . . Dmitry Petrov
  10. 10. Data Transfer Object DTO DomainObject1 DTO attribute1: String Assembler attribute1: String attribute2: String createDTO updateDomainObject serialize deserialize DomainObject2 attribute2: String Dmitry Petrov
  11. 11. Examples of DTO GET /api/orders/12 The server response: { "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. 12. Examples of DTO { "transition": "start:printing:front", "note": null } { "label": "epl string" } [ { "path":"/home/somepath/", "types": [ "34-f-Type", ...... ] }, ...... ] Dmitry Petrov
  13. 13. The benefits of using DTO patternReducing the number of queriesIndependence from API"Makes you think" Dmitry Petrov
  14. 14. Popular bundles and examples FOSRestBundle JMSSerializerBundle LiipHelloBundle FOSCommentBundle Dmitry Petrov
  15. 15. JMSSerializerBundle & GET method GET /api/orders/12 The server response: { "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. 16. JMSSerializerBundle & POST methodPOST /api/orders,Body of the request:{ "id": 12, "client": { "firstname": "Dmitry", "lastname": "Petrov", "email": "", "phone": null, "address": { "country": "Russia", "city": "Saratov", "zip": 123456, "street": "Vavilova", "residentional": false } }} Dmitry Petrov
  17. 17. JMSSerializerBundle & PATCH method Dmitry Petrov
  18. 18. JMSSerializerBundle $this->deserialize($request, RestOrderDTO, json); Dmitry Petrov
  19. 19. JMSSerializerBundle MERGE $this->merge($oldDTO, $newDTO); Dmitry Petrov
  20. 20. Merging DTO Dmitry Petrov
  21. 21. JMSSerializerBundle & PATCH methodPATCH /api/orders/12Request:{ "client": { "email": "", "phone": null }} Dmitry Petrov
  22. 22. RESTful API, JMSSerializerBundle Problems / DisadvantagesGET - serialization of null valuesPATCH - deserialized into an objectPATCH - merge null valuesMERGE - a lot of useless code Dmitry Petrov
  23. 23. SimpleThingsFormSerializerBundle SimpleThingsFormSerializerBundle July 15, 2012 Dmitry Petrov
  24. 24. SimpleThingsFormSerializerBundle Dmitry Petrov
  25. 25. SimpleThingsFormSerializerBundleGET /api/orders/12The server response:{ "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. 26. SimpleThingsFormSerializerBundle Problems / DisadvantagesConverting data into stringLack of support PATCH method (v. 2.0)The ideological aversionThe dirty mix *Type and *DTO Dmitry Petrov
  27. 27. Отпуск Dmitry Petrov
  28. 28. Отпуск Dmitry Petrov
  29. 29. Отпуск Dmitry Petrov
  30. 30. Reinvent the wheel Requirements (Un)Serialization of objects Preservation of the type in data Metadata cache Dmitry Petrov
  31. 31. Reinvent the wheel Assumptions The output format is json Metadata is stored in yml There are get/set methods Dmitry Petrov
  32. 32. Reinvent the wheel After 36 hours... train Saratov - Kiev is comming 30 hours SimpleSerializer SimpleSerializerBundle Details can be found on the habr Dmitry Petrov
  33. 33. SimpleSerializer BenefitsThis is librarySeparation of serialization rules and formatAbsence voiced disadvantages"Inteligent" deserialization Dmitry Petrov
  34. 34. SimpleSerializer & POST / PATCH Dmitry Petrov
  35. 35. SimpleSerializer & POST method Dmitry Petrov
  36. 36. RESTful API, validation What? Where? When? Parameters of requests Data transfer objects Business logic Dmitry Petrov
  37. 37. RESTful API, validation Parameters of requests /api/orders/12 /api/boxes/BOX-1-1 /api/orders?valid=true Dmitry Petrov
  38. 38. RESTful API, validation Routing requirements Dmitry Petrov
  39. 39. RESTful API, validation ParameterChecker Dmitry Petrov
  40. 40. RESTful API, validation Dmitry Petrov
  41. 41. RESTful API, validation Dmitry Petrov
  42. 42. RESTful API, validation AbstractRestController Dmitry Petrov
  43. 43. RESTful API, validation PATCH /api/orders/12 Object: Body of the request: { { "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. 44. RESTful API, validation Object: POST /api/press-sheets/12/transition { Body of the request: "transition": "start:printing:front", { "note": null "transition": "start:printing:front", } "note": null, "comment": "Im hacker" } POST /api/press-sheets/12/transition Body of the request: { "transition": "start:printing:front", "comment": "Im hacker" } Dmitry Petrov
  45. 45. RESTful API, validation How, where and when to handle these situations? Dmitry Petrov
  46. 46. REST APIs with Symfony2: The Right Way Dmitry Petrov
  47. 47. REST APIs with Symfony2: The Right Way Disadvantages Conventionalism Duplication of code Only works as filter Dmitry Petrov
  48. 48. SimpleSerializer "Inteligent" deserialization 3 modes of deserialization: Strict, Medium strict, Non-strict + Support groups Dmitry Petrov
  49. 49. RESTful API, handle of DTO Dmitry Petrov
  50. 50. RESTful API, handle of domain object Dmitry Petrov
  51. 51. RESTful API, testing Behat, PHPUnit Controllers Data access layer Service layer Dmitry Petrov
  52. 52. RESTful API, Behat scenario Dmitry Petrov
  53. 53. RESTful API, testing Problems Run time: Behat ~ 90 minutes PHPUnit ~ 5 minutes Dmitry Petrov
  54. 54. RESTful API, authentication WSSEAtom AuthenticationHow to create a custom Authentication ProviderEscapeWSSEAuthenticationBundle (v. 2.0)MopaWSSEAuthenticationBundle (v. 2.1) Dmitry Petrov
  55. 55. RESTful API, authentication WSSE Header X-WSSE: UsernameToken Username="bob", PasswordDigest="quR/EWLAV4xLf9Zqyw4pDmfV9OY=", Nonce="d36e316282959a9ed4c89851497a717f", Created="2003-12-15T14:43:07Z" Dmitry Petrov
  56. 56. RESTful API, authentication Password digest Base64 (SHA1 (Nonce + CreationTimestamp + Password)) Dmitry Petrov
  57. 57. RESTful API, The End Dmitry Petrov
  58. 58. RESTful API Any questions? @old_fightmaster https://github.com/opensoft https://github.com/fightmaster Special thanks to ProFIT team Dmitry Petrov
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×