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

Domain-Driven Design & REST

Domain-Driven Design & REST

Slides of the talk I gave at Spring I/O 2016.

@springcentral

977c74bb044a9d4fa90b305824eda390?s=128

Oliver Drotbohm

May 19, 2016
Tweet

Transcript

  1. DDD & REST Domain-Driven APIs for the web / olivergierke

    Oliver Gierke
  2. 2

  3. Background 3

  4. 4 Spring Data Repositories &
 Aggregates Spring HATEOAS Hypermedia
 for

    Spring MVC Spring Data REST
  5. REST ≠ 
 CRUD via HTTP 5

  6. What does it take to bridge the worlds of DDD

    & REST? “ 6
  7. None
  8. 8 http://www.infoq.com/minibooks/domain-driven-design-quickly

  9. 9

  10. 9

  11. Implementing Domain-Driven Design 10

  12. Value objects 11

  13. Stringly typed code 12 public class Customer { private Long

    id; private String firstname, lastname, email; … }
  14. Stringly typed code 13 public class SomeService { public void

    createUser(String firstname,
 String lastname, String email) { … } }
  15. 14 public class Customer { private Long id; private Firstname

    firstname; private Lastname lastname; private EmailAddress emailAddress; … }
  16. Value Objects are a
 PITA to build in
 some languages.

    15
  17. Still, they’re worth it. 16 See „Power Use of Value

    Objects in DDD“ by Dan Bergh Johnsson.
  18. Lombok — putting the spice back into Java. 17

  19. 18 @Value public class Customer { UUID id = UUID.randomUUID();

    Firstname firstname; Lastname lastname; EmailAddress email; @Value static class EmailAddress { String value; } }
  20. AutoValue 19 Project website on GitHub.

  21. Key opponents: Mapping libraries
 that need to
 (de)serialize them. 20

  22. Entities & Repositories 21

  23. 22 Order LineItem Product Invoice Customer Payment Address Email

  24. 22 Order LineItem Product Invoice Customer Payment Address Email

  25. Entity +
 Repository = 
 Aggregate 23

  26. Aggregates form nice representation boundaries. 24

  27. Aggregates become
 the key things
 to refer to. 25

  28. Don’t get trapped by datastore thinking. 26

  29. Try to avoid 
 bi-directional relationships. 27

  30. Bounded Context 28

  31. Order LineItem Product Invoice Customer Payment Address

  32. 30 Shipping Accounting Catalog Orders User
 Registration

  33. 30 Shipping Accounting Catalog Orders User
 Registration Accounting Payment information

    Billing Address Shipping Shipping address Customer Product
  34. Domain Events 31

  35. 32 Level 0: No events at all

  36. 32 Level 0: No events at all Level 1: Explicit

    operations
  37. If you’re calling two setters in a row, you’re missing

    a concept. 33
  38. 34 Level 0: No events at all Level 1: Explicit

    operations
  39. 34 Level 0: No events at all Level 1: Explicit

    operations Level 2: Some operations as events
  40. Domain events as
 state transitions. 35

  41. Expose important
 events to interested parties via feeds. 36

  42. 37 Level 0: No events at all Level 1: Explicit

    operations Level 2: Some operations as events
  43. 37 Level 0: No events at all Level 1: Explicit

    operations Level 2: Some operations as events Level 3: Event Sourcing
  44. REST 38

  45. Representation design matters 39

  46. Aggregates Identifiable
 Referable
 Scope of consistency 40

  47. Resources Identifiable
 Referable
 Scope of consistency 41

  48. Hypermedia 42

  49. Serving data and navigation information
 at the same time. 43

  50. Trading domain knowledge with protocol complexity in clients. 44

  51. Reducing decisions in clients to whether a
 link is present

    or not. 45
  52. Prefer explicit 
 state transitions over poking at your resources

    using PATCH. 46
  53. Translate domain concepts into web- appropriate ones. 47

  54. 48 Aggregate Root / Repository Collection / Item Resources IDs

    URIs @Version ETags Last Modified Property Last Modified Header Relations Links
  55. RESTBucks payment expected preparing cancelled ready completed 1 2 3

    4 5 6
  56. Method URI Action Step POST /orders Create new order 1

    POST/PATCH /orders/{id} Update the order (only if "payment expected") 2 DELETE /orders/{id} Cancel order (only if "payment expected") 3 PUT /orders/{id}/payment Pay order (only if "payment expected") 4 Barista preparing the order GET /orders/{id} Poll order state 5 GET /orders/{id}/receipt Access receipt DELETE /orders/{id}/receipt Conclude the order process 6
  57. Method Resource type Action Step POST orders Create new order

    1 POST/PATCH update Update the order 2 DELETE cancel Cancel order 3 PUT payment Pay order 4 Barista preparing the order GET order Poll order state 5 GET receipt Access receipt DELETE receipt Conclude the order process 6
  58. 52 GET /orders { „_links“ : { „cancel“ : {

    „href“ : … }, … „createdDate“ : …, „status“ : „Payment expected“ … }
  59. 53 GET /orders { „_links“ : { „cancel“ : {

    „href“ : … }, … „createdDate“ : …, „status“ : „Payment expected“ … }
  60. 54 “Internationalize
 all user facing text.

  61. Aaaargh! 55

  62. 56 GET /orders { „_links“ : { „cancel“ : {

    „href“ : … }, … „createdDate“ : …, „status“ : „Payment expected“ … }
  63. Spring RESTBucks 57

  64. Web Service Repository - Orders Spring Data Spring Data
 REST

    Payment Spring Data Manual
 implementation Manual
 implementation
  65. JacksonCustomizations Externalize tweaks to the general JSON design 59

  66. Spring Data REST
 for the CRUDdy parts. 60

  67. ResourceProcessor To conditionally sneak links into the default representation. 61

  68. Resources 62 Spring RESTBucks
 https://github.com/olivergierke/spring-restbucks Benefits of Hypermedia APIs
 http://olivergierke.de/2016/04/benefits-of-hypermedia/index.html

  69. Questions? 63