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

Handle complex POST/PATCH requests in RESTful API

Dmitry Petrov
December 12, 2012
170

Handle complex POST/PATCH requests in RESTful API

Report with a speech on the 2012 sfcampua

Dmitry Petrov

December 12, 2012
Tweet

Transcript

  1. ProFIT Dmitry Petrov Daily: ~ 1 000 orders ~1 000

    000 print productions 1 hour of downtime ~ 25 000$ Product Fulfillment and Information Tracking
  2. RESTful API Dmitry Petrov ~ 60 entity ~100 API endpoints

    Complex business logic RESTful API for ProFIT
  3. Dmitry Petrov GET /api/orders/12/items/fg45sf54 The server response: { "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 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 } } } RESTful API, examples GET
  4. Dmitry Petrov GET /api/product-box-types/12-type/associations The server response: [ { "id":

    1, "product": "business_cards", "quantity": 1000 }, ...... ] GET /api/machines/KARAT+1/hot-folders The server response: [ { "path":"/home/somepath/", "types": [ "34-f-Type", "33-S-Type", ...... ] }, ...... ] GET /api/press-sheets/134/label The server response: { "label": "epl string" } RESTful API, examples GET
  5. Dmitry Petrov POST http://localhost/api/press-sheets/12/transition Body of the request: { "transition":

    "start:printing:front", "note": null } POST http://localhost/api/orders, PUT http://localhost/api/orders/12 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 } } } RESTful API, examples POST / PUT
  6. Dmitry Petrov PATCH http://localhost/api/orders/12 Body of the request: { "client":

    { "email": "", "phone": null } } PATCH http://localhost/api/orders/12 Body of the request: { "client": { "email": "" }, "address": { "street": "Vavilova", "residentional": true } } Object: { "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, examples PATCH
  7. DTO Dmitry Petrov Data Transfer Object DTO attribute1: String attribute2:

    String Assembler createDTO updateDomainObject serialize deserialize DomainObject1 attribute1: String DomainObject2 attribute2: String
  8. Dmitry Petrov 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 } } } Examples of DTO
  9. Dmitry Petrov { "transition": "start:printing:front", "note": null } { "label":

    "epl string" } [ { "path":"/home/somepath/", "types": [ "34-f-Type", ...... ] }, ...... ] Examples of DTO
  10. Dmitry Petrov Reducing the number of queries Independence from API

    "Makes you think" The benefits of using DTO pattern
  11. Dmitry Petrov 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 } } } JMSSerializerBundle & GET method
  12. Dmitry Petrov POST /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 } } } JMSSerializerBundle & POST method
  13. Dmitry Petrov PATCH /api/orders/12 Request: { "client": { "email": "",

    "phone": null } } JMSSerializerBundle & PATCH method
  14. Problems / Disadvantages Dmitry Petrov GET - serialization of null

    values PATCH - deserialized into an object PATCH - merge null values MERGE - a lot of useless code RESTful API, JMSSerializerBundle
  15. Dmitry Petrov GET /api/orders/12 The 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" } } } SimpleThingsFormSerializerBundle
  16. Problems / Disadvantages Dmitry Petrov Converting data into string Lack

    of support PATCH method (v. 2.0) The ideological aversion The dirty mix *Type and *DTO SimpleThingsFormSerializerBundle
  17. Assumptions Dmitry Petrov The output format is json Metadata is

    stored in yml There are get/set methods Reinvent the wheel
  18. After 36 hours... train Saratov - Kiev is comming 30

    hours Dmitry Petrov SimpleSerializer SimpleSerializerBundle Details can be found on the habr Reinvent the wheel
  19. Benefits Dmitry Petrov This is library Separation of serialization rules

    and format Absence voiced disadvantages "Inteligent" deserialization SimpleSerializer
  20. What? Where? When? Dmitry Petrov Parameters of requests Data transfer

    objects Business logic RESTful API, validation
  21. Dmitry Petrov PATCH /api/orders/12 Body of the request: { "client":

    { "email": "", "comment": "I'm hacker" } } Object: { "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, validation
  22. Dmitry Petrov POST /api/press-sheets/12/transition Body of the request: { "transition":

    "start:printing:front", "note": null, "comment": "I'm hacker" } POST /api/press-sheets/12/transition Body of the request: { "transition": "start:printing:front", "comment": "I'm hacker" } Object: { "transition": "start:printing:front", "note": null } RESTful API, validation
  23. WSSE Dmitry Petrov Atom Authentication How to create a custom

    Authentication Provider EscapeWSSEAuthenticationBundle (v. 2.0) MopaWSSEAuthenticationBundle (v. 2.1) RESTful API, authentication