Advertisement
Advertisement

More Related Content

Similar to BoilingFrogs - Rozterki i decyzje. Czego się nauczyliśmy projektując API Syliusa(20)

Advertisement

Recently uploaded(20)

BoilingFrogs - Rozterki i decyzje. Czego się nauczyliśmy projektując API Syliusa

  1. @lukaszchrusciel Rozterki i Rozterki i decyzje. decyzje. Czego się nauczyliśmy projektując Czego się nauczyliśmy projektując API Syliusa API Syliusa
  2. @lukaszchrusciel QUIZ QUIZ
  3. @lukaszchrusciel Introduction Introduction
  4. @lukaszchrusciel
  5. @lukaszchrusciel
  6. @lukaszchrusciel
  7. @lukaszchrusciel
  8. @lukaszchrusciel Started in 2020 Started in 2020 1.12 with API Platform 2.7 1.12 with API Platform 2.7 (since 31st of Oct) 1.13 stabilized with API 1.13 stabilized with API Platform 3.0 Platform 3.0
  9. @lukaszchrusciel Decisions & Decisions & consequences consequences
  10. @lukaszchrusciel Strategic design Strategic design
  11. @lukaszchrusciel ADRs ADRs
  12. @lukaszchrusciel QUIZ QUIZ
  13. @lukaszchrusciel Architecture Decision Architecture Decision Records Records
  14. @lukaszchrusciel Architecture Decision Records Architecture Decision Records [short title of solved problem and solution] Status: [proposed | rejected | ... ] Date: [YYYY-MM-DD] Context and Problem Statement Decision Drivers [driver 1, e.g., a force, facing concern, …] … Considered Options [option 1] Good, because [argument a] Bad, because [argument b] … Decision Outcome Chosen option: "[option 1]", because [justification]. References [Link type] [Link to ADR]
  15. @lukaszchrusciel Architecture Decision Records Architecture Decision Records [short title of solved problem and solution] Status: [proposed | rejected | ... ] Date: [YYYY-MM-DD] Context and Problem Statement Decision Drivers [driver 1, e.g., a force, facing concern, …] … Considered Options [option 1] Good, because [argument a] Bad, because [argument b] … Decision Outcome Chosen option: "[option 1]", because [justification]. References [Link type] [Link to ADR]
  16. @lukaszchrusciel Architecture Decision Records Architecture Decision Records [short title of solved problem and solution] Status: [proposed | rejected | ... ] Date: [YYYY-MM-DD] Context and Problem Statement Decision Drivers [driver 1, e.g., a force, facing concern, …] … Considered Options [option 1] Good, because [argument a] Bad, because [argument b] … Decision Outcome Chosen option: "[option 1]", because [justification]. References [Link type] [Link to ADR]
  17. @lukaszchrusciel Architecture Decision Records Architecture Decision Records [short title of solved problem and solution] Status: [proposed | rejected | ... ] Date: [YYYY-MM-DD] Context and Problem Statement Decision Drivers [driver 1, e.g., a force, facing concern, …] … Considered Options [option 1] Good, because [argument a] Bad, because [argument b] … Decision Outcome Chosen option: "[option 1]", because [justification]. References [Link type] [Link to ADR]
  18. @lukaszchrusciel Architecture Decision Records Architecture Decision Records [short title of solved problem and solution] Status: [proposed | rejected | ... ] Date: [YYYY-MM-DD] Context and Problem Statement Decision Drivers [driver 1, e.g., a force, facing concern, …] … Considered Options [option 1] Good, because [argument a] Bad, because [argument b] … Decision Outcome Chosen option: "[option 1]", because [justification]. References [Link type] [Link to ADR]
  19. @lukaszchrusciel Architecture Decision Records Architecture Decision Records [short title of solved problem and solution] Status: [proposed | rejected | ... ] Date: [YYYY-MM-DD] Context and Problem Statement Decision Drivers [driver 1, e.g., a force, facing concern, …] … Considered Options [option 1] Good, because [argument a] Bad, because [argument b] … Decision Outcome Chosen option: "[option 1]", because [justification]. References [Link type] [Link to ADR]
  20. @lukaszchrusciel Conclusion Conclusion Conclusion Conclusion Architecture Architecture Architecture Architecture Decision Records Decision Records Decision Records Decision Records FTW FTW FTW FTW [short title of solved problem and solution] Status: [proposed | rejected | ... ] Date: [YYYY-MM-DD] Context and Problem Statement Decision Drivers [driver 1, e.g., a force, facing concern, …] … Considered Options [option 1] Good, because [argument a] Bad, because [argument b] … Decision Outcome Chosen option: "[option 1]", because [justification]. References [Link type] [Link to ADR]
  21. @lukaszchrusciel GraphQL vs REST GraphQL vs REST
  22. @lukaszchrusciel 2020 2020 GraphQL GraphQL
  23. @lukaszchrusciel Is it still? Is it still?
  24. @lukaszchrusciel
  25. @lukaszchrusciel
  26. @lukaszchrusciel Is it not? Is it not?
  27. @lukaszchrusciel GraphQL GraphQL Solves over fetching Solves over fetching and under fetching and under fetching By design
  28. @lukaszchrusciel GraphQL GraphQL Sends everything with Sends everything with POST POST It is possible to do it with GET
  29. @lukaszchrusciel GraphQL GraphQL Typed, nice Typed, nice documentation documentation out of the box
  30. @lukaszchrusciel GraphQL GraphQL Gracefully deprecation Gracefully deprecation of queries of queries Which was not possible with default REST
  31. @lukaszchrusciel GraphQL GraphQL Promise high Promise high performance performance due to reduction of queries
  32. @lukaszchrusciel REST REST May solve over May solve over fetching and under fetching and under fetching fetching With sparefields sets and/or Vulcain
  33. @lukaszchrusciel REST REST Takes advantage of 30 Takes advantage of 30 years of web cache years of web cache development development Fake data institute™
  34. @lukaszchrusciel REST REST Typed, nice Typed, nice documentation documentation With OpenAPI
  35. @lukaszchrusciel REST REST Gracefully deprecation Gracefully deprecation of queries of queries With OpenAPI and HTTP Headers
  36. @lukaszchrusciel Quiz Quiz
  37. @lukaszchrusciel In 2022 (...) REST API usage in production grew by 10% now at 70% compared to GraphQL 5% increased usage. 1 https://rapidapi.com/guides/2022-state-of-apis-what-developers-are-saying 1.
  38. @lukaszchrusciel Conclusion Conclusion REST is a better default REST is a better default
  39. @lukaszchrusciel High level API High level API design design
  40. @lukaszchrusciel Unification of API Unification of API
  41. @lukaszchrusciel Shop vs Shop vs Admin Admin
  42. @lukaszchrusciel Shop Shop 72 endpoints 72 endpoints 64% of read endpoints 64% of read endpoints 20% of resources have 20% of resources have writable capabilities writable capabilities Admin Admin 128 endpoints 128 endpoints 52% of read endpoints 52% of read endpoints 40% of them are never 40% of them are never exposed in shop exposed in shop
  43. @lukaszchrusciel Option #1 Option #1 Admin & Shop served together Admin & Shop served together /api/products/
  44. @lukaszchrusciel Findings Findings Available fields Available fields Complicated serialisation groups depending on logged in user Requires granular access control Requires granular access control To not allow to access sensitive date for non-admins Hard to define different identifiers Hard to define different identifiers We have resigned from them later Good from REST perspective Good from REST perspective
  45. @lukaszchrusciel Option #2 Option #2 Admin & Shop suffixed Admin & Shop suffixed /api/products/?admin
  46. @lukaszchrusciel Findings Findings Available fields Available fields Depending on logged in user Requires granular access control Requires granular access control To not allow to access sensitive date for non-admins Seems wrong from the REST perspective Seems wrong from the REST perspective If we add suffix for different representation
  47. @lukaszchrusciel Option #3 Option #3 Admin & Shop header split Admin & Shop header split /api/products/ Accept: application/vnd.sylius- admin.api+json
  48. @lukaszchrusciel Findings Findings Available fields Available fields Depending on logged in user Requires granular access control Requires granular access control To now allow to access sensitive date for non- admins REST compilant REST compilant
  49. @lukaszchrusciel Option #4 Option #4 Admin & Shop prefixed Admin & Shop prefixed /api/shop/products/ /api/admin/products/
  50. @lukaszchrusciel Findings Findings Available fields Available fields Depending on logged in user Straightforward access control Straightforward access control Just with security config / / REST compilant REST compilant Disputable / / Easily supported Easily supported By API Platform and by Open API spec
  51. @lukaszchrusciel QUIZ QUIZ
  52. @lukaszchrusciel Conclusion Conclusion Custom headers are the Custom headers are the way to go way to go But But We chose the resource split We chose the resource split
  53. @lukaszchrusciel API versioning API versioning
  54. @lukaszchrusciel What we had What we had /api/v1
  55. @lukaszchrusciel WIP WIP /new-api/
  56. @lukaszchrusciel Option #1 Option #1 URL based versioning URL based versioning /api/v2
  57. @lukaszchrusciel Option #2 Option #2 Accept header with version Accept header with version Accept: application/vnd.sylius.v1+json
  58. @lukaszchrusciel Option #3 Option #3 Custom header Custom header X-Sylius-API-Version: 1
  59. @lukaszchrusciel
  60. @lukaszchrusciel QUIZ QUIZ
  61. @lukaszchrusciel
  62. @lukaszchrusciel Conclusion Conclusion API Evolution API Evolution Version in header Version in header We chose versioning in URL We chose versioning in URL
  63. @lukaszchrusciel API flow API flow design design
  64. @lukaszchrusciel Case #1 Case #1 Add to cart Add to cart
  65. @lukaszchrusciel Simple product Simple product { "product": "/api/products/42", "quantity": 1 }
  66. @lukaszchrusciel Configurable product #1 Configurable product #1 { "product": "/api/products/42", "productVariant": "/api/variants/42", "quantity": 1 }
  67. @lukaszchrusciel Configurable product #2 Configurable product #2 { "product": "/api/products/42", "options": { "SIZE": "SIZE_L", "COLOR": "COLOR_BLUE" }, "quantity": 1 }
  68. @lukaszchrusciel Let’s improve! Let’s improve!
  69. @lukaszchrusciel Simple Simple product product { "product": "/api/products/42", "quantity": 1 } Configurable Configurable product product { "product": "/api/products/8", "productVariant": "/api/variants/864", "quantity": 1 }
  70. @lukaszchrusciel Simple Simple product product { "product": "/api/products/42", "productVariant": "/api/variants/42", "quantity": 1 } Configurable Configurable product product { "product": "/api/products/8", "productVariant": "/api/variants/864", "quantity": 1 }
  71. @lukaszchrusciel Simple & Configurable product Simple & Configurable product { "product": "/api/products/8", "productVariant": "/api/variants/42", "quantity": 1 }
  72. @lukaszchrusciel Simple & Configurable product Simple & Configurable product { "productVariant": "/api/variants/42", "quantity": 1 }
  73. @lukaszchrusciel But what with options? But what with options?
  74. @lukaszchrusciel Price matrix in UI Price matrix in UI or or Ask us Ask us
  75. @lukaszchrusciel Case #2 Case #2 Order details Order details
  76. @lukaszchrusciel
  77. @lukaszchrusciel Apply coupon PATCH /api/orders/TOKEN_VALUE /apply-coupon { "couponCode": "CHRISTMAS_SALE" }
  78. @lukaszchrusciel
  79. @lukaszchrusciel Cart claiming & addressing PATCH /api/orders/TOKEN_VALUE/address { "email": "test@example.com", "billingAddress": { "firstName": "Jane", "lastName": "Doe", "...": "..." } }
  80. @lukaszchrusciel Reasoning? Reasoning? We are used to this separation We are used to this separation Mockups “force” such design Different data required on different pages Different data required on different pages Addressing requires state machine Addressing requires state machine transition transition Adding coupon requires recalculation
  81. @lukaszchrusciel What about order What about order update? update?
  82. @lukaszchrusciel Order update Order update PUT /api/orders/TOKEN_VALUE { "localeCode": "en_US" }
  83. @lukaszchrusciel But it is just order But it is just order drafting! drafting!
  84. @lukaszchrusciel Changed attitude Changed attitude UI Mockups should not force any UI Mockups should not force any design decision design decision We can preload data from more then one endpoint Use partial update Use partial update Don’t use state machine where there Don’t use state machine where there is none is none
  85. @lukaszchrusciel Order update Order update PUT /api/orders/TOKEN_VALUE { "email": "test@example.com", "billingAddress": { "firstName": "Jane", "lastName": "Doe", "...": "..." }, "couponCode": "CHRISTMAS_SALE" }
  86. @lukaszchrusciel Conclusion Conclusion Don't let mockups force Don't let mockups force you API design you API design
  87. @lukaszchrusciel State transitions State transitions
  88. @lukaszchrusciel Case Case Let’s cancel an Let’s cancel an order! order!
  89. @lukaszchrusciel Considered option #1 Considered option #1 PATCH /api/orders/42/ { "state": "cancelled" }
  90. @lukaszchrusciel Considered option #2 Considered option #2 PATCH /api/orders/42/cancel {}
  91. @lukaszchrusciel
  92. @lukaszchrusciel RESTful Archetypes RESTful Archetypes
  93. @lukaszchrusciel RESTful Archetypes RESTful Archetypes Document Document /api/admin/orders/1 Collections Collections Server controlled /api/admin/orders Store Store Client controlled /api/admin/orders/123 Controller Controller /api/admin/orders/1/cancel 1 Based on: REST API Design Rulebook by Mark Masse 1.
  94. @lukaszchrusciel Isn’t there a better way? Isn’t there a better way?
  95. @lukaszchrusciel Considered option #3 Considered option #3 POST /api/orders- cancellation-requests/ {}
  96. @lukaszchrusciel QUIZ QUIZ
  97. @lukaszchrusciel Conclusion Conclusion Express your operation Express your operation as resources as resources
  98. @lukaszchrusciel Takeaways Takeaways Use ADRs Use ADRs And browse them from time to time REST will be with us for the REST will be with us for the long time long time But GraphQL will be there as well Custom logic? New API Custom logic? New API resource! resource! Let’s behave like a tax department! Do not map HTML based Do not map HTML based websites to your API websites to your API I know, it was obvious
  99. @lukaszchrusciel Thank Thank you! you!
Advertisement