A Quick walkthrough the Richardson REST Maturity Model with simple examples, followed by design considerations for building software for a REST architectural style. Key point: REST is the starting position, not the end point when designing.
4. I did do this...create quote
POST /quoteService
<QuoteRequestMessage ...
quote
service
200 OK
<Quote ...
5. and this … accept quote
POST /quoteService
<AcceptQuoteMessage ...
quote
service
200 OK
<StatusMessage ...
6. and this … exceptions
POST /quoteService
<AcceptQuoteMessage ...
quote
service
200 OK
<Error ...
7. REST(0)
POST /quoteService
<QuoteRequestMessage ...
slinging XML
quote
service
200 OK
<Quote ...
POST /quoteService
<AcceptQuoteMessage ...
quote
service
RPC == true
200 OK
REST == false
<StatusMessage ...
POST /quoteService
<AcceptQuoteMessage ...
quote
service
200 OK
<Error ...
no uniformity => accidental complexity
9. enter WS_*
do contract first
xml schema + wsdl + soap + ...
ptaaanngg!! ... oops … sniper shot
feels like static typing in a dynamic world
10. WS-*
POST /quoteService
<QuoteRequestMessage ...
slinging XML
quote
service
200 OK
<Quote ...
POST /quoteService
<AcceptQuoteMessage ...
with envelopes
quote
service
200 OK
<StatusMessage ...
Complex remote access protocol
POST /quoteService
<AcceptQuoteMessage ...
quote
service
200 OK
<Error ...
toolsets are symptomatic of the complexity
12. Next attempt … many endpoints
POST /customer/176202?fromDate...
/customer
200 OK
<Quote id="Q91827"
POST /quote?ref=Q91827
/quote
200 OK
<Policy...
13. same thing … just friendly
POST <FindQuote fromDate="...
/customer/176202
200 OK
<Quote id="Q91827"
POST <AcceptQuote
/quote/Q91827
200 OK
<Policy...
14. but I can almost imagine the model
customer
findQuote(...)
*
quote
policy accept(...)
16. How about this … verb idioms
GET /customer/176202/quotes?from...
/customer
200 OK
<Quote id="Q91827"
POST /quote/Q91827
<Acceptance ...
/quote
201 OK
Location: /policy/PX81730Z9...
<Policy id="PX81730Z9...
17. Predictability is more important than
GET retrieve
POST create
PUT update
DELETE delete
don’t be dogmatic, be pragmatic
think safe vs unsafe and side-effects
18. Again, being predictable
201 created
409 conflict
401 unauthorised
... ...
uniformity is a powerful force
19. REST(2)
HTTP Verbs
+response codes
uniformity + unsafe vs safe operations
but dumping a ton of URI’s on your friends is not very nice
20. This is the next step
GET /customer/176202
/customer
200 OK
<Customer id="Q91827" ...
<links>
<link rel='find quotes'
uri='/quotes/176202"/>
<link rel='policy' uri='/policy/PX81730Z9"/>
21. and so on ...
GET /quotes/Q91827
200 OK
<Quotes customer="176202" ...
<quote id="Q91827"
<links>
<link rel='accept quote'
uri='/blahblah?id="Q91827"/>
<link rel='cancel quote'
uri='/ushoqwbyw/198n392/>
22. state changed?
GET /quotes/Q91827
200 OK
<Quotes customer="176202" ...
<quote id="Q91827"
<links>
<link rel="self" uri='/quote/Q91827"/>
</link>
25. this is the signal
in the noise!
But it is always about design.
How do you design when REST
is your architectural style?
REST is not the end goal, it is
actually your starting position.
And it’s not for everything.
26. REST(0)
REST(1)
This is a
REST(2) design choice.
ranges from exploiting HTTP
to honoring HTTP
REST(3)
27. Some context first
Design, for me, is just answering two questions.
1. Does that thing express its intention?
2. Where should I put that thing?
29. resource overloading is not reuse
doubling up a resource to serve more than
its single purpose is more likely to introduce
accidental complexity than visible benefit.
+
there is no cost to having lots of resources
(if there is, you have a bigger problem)
the set of resources is open ended
30. Refer to self is important
POST /customer
<customer> ... </customer>
200 OK
<customer id=194839>
...
<links>
<link rel=”self” uri=”/customer/194839>
</links>
</customer>
no need to expose /customer/{customer_id}
reduce URI explosions
31. Jou ma se State!
customer
findQuote(...)
*
quote
policy accept(...)
domain state resource state application state
app state can be inferred
32. Search
/policy /claim /customer
Find all resources where Find all claims that are
there is an email address approved but unpaid and
“aslam.khan@factor10.com” where the policy is paid up
create another resource for the result … and then?
33. Domain : Resource Impedance
GET /lastmovement/CA28382
vehicle
{ registration : Ca28382,
last_movement: {
? odo: 78282,
*
lat: ...
movement
}
position links { ... }
}
aggregates ==
resources?
entities == resources?
not necessarily
it is still a bi-directional mapping
no domain model?
problem
where should we model
behavior?
34. Thanks, and so long
def valuable?(signal, noise)
(signal.power/noise.power) > 1
end
valuable?(hype, design).should == false
valuable?(design, hype).should == true
obligatory ruby code slide