five inconvenient truths about rest

66
FIVE INCONVENIENT TRUTHS ABOUT REST Filip van Laenen 1 https://www.flickr.com/photos/grantmac/4192158869

Upload: filip-van-laenen

Post on 18-Feb-2017

241 views

Category:

Software


0 download

TRANSCRIPT

Page 1: Five Inconvenient Truths about REST

FIVE INCONVENIENT TRUTHS ABOUT RESTFilip van Laenen

1https://www.flickr.com/photos/grantmac/4192158869

Page 2: Five Inconvenient Truths about REST

Who Am I?

2

● 18 years of experience as a developer/architect

● Been involved in a number of REST projects

– Client/consumer

– Server/producer

● Things I wish I knew a couple of years ago…

http://www.slideshare.net/filipvanlaenen/

Page 3: Five Inconvenient Truths about REST

REST – Representational state transfer

3

From Wikipedia:

“Representational State Transfer (REST) is a software architecture style for building scalable web services.

REST gives a coordinated set of constraints to the design of components in a distributed hypermedia system that can lead to a higher performing and more maintainable architecture.”

Page 4: Five Inconvenient Truths about REST

REST – Representational state transfer

4

From Wikipedia:

“RESTful systems typically, but not always, communicate over the Hypertext Transfer Protocol with the same HTTP verbs (GET, POST, PUT, DELETE, etc.) which web browsers use to retrieve web pages and to send data to remote servers.

REST interfaces usually involve collections of resources with identifiers, for example /people/paul, which can be operated upon using standard verbs, such as DELETE /people/paul.”

Page 5: Five Inconvenient Truths about REST

5http://martinfowler.com/articles/richardsonMaturityModel.html

Richardson Maturity Model

Page 6: Five Inconvenient Truths about REST

So, what's wrong with REST?

6

Page 7: Five Inconvenient Truths about REST

Ever Heared a REST-Discussion about “State”?

7

Page 8: Five Inconvenient Truths about REST

Ever Heared a REST-Discussion about “State”?

8

From Wikipedia:

“The client–server communication is constrained by no client context being stored on the server between requests.”

Page 9: Five Inconvenient Truths about REST

INCONVENIENT TRUTH #1:

GET calls are never nullipotent

9https://www.flickr.com/photos/grantmac/4192158869

Page 10: Five Inconvenient Truths about REST

10http://martinfowler.com/articles/richardsonMaturityModel.html

Richardson Maturity Model

Page 11: Five Inconvenient Truths about REST

What does «nullipotent» mean?

11

From Wikipedia:

“The GET method is a safe method (or nullipotent), meaning that calling it produces no side-effects.”

Page 12: Five Inconvenient Truths about REST

What does «nullipotent» mean?

12

From Wikipedia:

“The GET method is a safe method (or nullipotent), meaning that calling it produces no side-effects.”

Page 13: Five Inconvenient Truths about REST

13

Tomcat Access Log

Page 14: Five Inconvenient Truths about REST

Wanted Side-effects

● Access log from a REST resource

● Access control

– Three strikes and you're out

● One-time downloads

– Think “Snapchat”

14

Page 15: Five Inconvenient Truths about REST

GET Methods with Side-effects Are OK

15

…if the side-effects are:

● General good practices

● Part of the domain

Page 16: Five Inconvenient Truths about REST

GET Methods with Side-effects Are OK

16

…if the side-effects are:

● General good practices

● Part of the domain

In other words:

● Unobservable

● Expected

Page 17: Five Inconvenient Truths about REST

INCONVENIENT TRUTH #2:

HTTP Verbs ≠ “REST Verbs”

17https://www.flickr.com/photos/grantmac/4192158869

Page 18: Five Inconvenient Truths about REST

18http://martinfowler.com/articles/richardsonMaturityModel.html

Richardson Maturity Model

Page 19: Five Inconvenient Truths about REST

19https://en.wikipedia.org/wiki/Representational_state_transfer

HTTP Verbs

Page 20: Five Inconvenient Truths about REST

20https://en.wikipedia.org/wiki/Representational_state_transfer

HTTP Verbs

Page 21: Five Inconvenient Truths about REST

HTTP/1.1 Spec about POST and PUT

21

The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line.

The PUT method requests that the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server. If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI.

Page 22: Five Inconvenient Truths about REST

HTTP/1.1 Spec about POST and PUT

22

The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line.

The PUT method requests that the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server. If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI.

Page 23: Five Inconvenient Truths about REST

HTTP/1.1 Spec about POST and PUT

23

The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line.

The PUT method requests that the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server. If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI.

Page 24: Five Inconvenient Truths about REST

HTTP/1.1 Spec about POST and PUT

24

The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line.

The PUT method requests that the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server. If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI.

Page 25: Five Inconvenient Truths about REST

25https://en.wikipedia.org/wiki/Representational_state_transfer

HTTP Verbs

Page 26: Five Inconvenient Truths about REST

INCONVENIENT TRUTH #3:

HTTP Response Codes ≠ “REST Response Codes”

26https://www.flickr.com/photos/grantmac/4192158869

Page 27: Five Inconvenient Truths about REST

27http://martinfowler.com/articles/richardsonMaturityModel.html

Richardson Maturity Model

Page 28: Five Inconvenient Truths about REST

Martin Fowler on HATEOAS

28

“The key elements that are supported by the existence of the web are the strong separation between safe (eg GET) and non-safe operations, together with using status codes to help communicate the kinds of errors you run into.”

http://martinfowler.com/articles/richardsonMaturityModel.html

Page 29: Five Inconvenient Truths about REST

29http://www.restapitutorial.com/httpstatuscodes.html

Page 30: Five Inconvenient Truths about REST

30http://www.restapitutorial.com/httpstatuscodes.html

Page 31: Five Inconvenient Truths about REST

31http://www.restapitutorial.com/httpstatuscodes.html

Page 32: Five Inconvenient Truths about REST

What If Something Else Is Wrong?

32

Semantical errors, but syntactically correct:

● References to resources that don't exist

● Illegal values

● Invalid combination of choices

● Anything else that doesn't make sense in your domain

Page 33: Five Inconvenient Truths about REST

33http://www.restapitutorial.com/httpstatuscodes.html

Page 34: Five Inconvenient Truths about REST

422 Unprocessable Entity

34

From IETF RFC 4918:

“The 422 (Unprocessable Entity) status code means the server understands the content type of the request entity (hence a 415 (Unsupported Media Type) status code is inappropriate), and the syntax of the request entity is correct (thus a 400 (Bad Request) status code is inappropriate) but was unable to process the contained instructions.

For example, this error condition may occur if an XML request body contains well-formed (i.e., syntactically correct), but semantically erroneous, XML instructions.”

https://tools.ietf.org/html/rfc4918#section-11.2

Page 35: Five Inconvenient Truths about REST

35http://www.restapitutorial.com/httpstatuscodes.html

Page 36: Five Inconvenient Truths about REST

INCONVENIENT TRUTH #4:

HATEOAS YAGNI⇒

36https://www.flickr.com/photos/grantmac/4192158869

Page 37: Five Inconvenient Truths about REST

37Fra: http://martinfowler.com/articles/richardsonMaturityModel.html

Richardson Maturity Model

Page 38: Five Inconvenient Truths about REST

HATEOAS

38

Hypermedia as the engine of application state

From Wikipedia:

“Clients make state transitions only through actions that are dynamically identified within hypermedia by the server.

Except for simple fixed entry points to the application, a client does not assume that any particular action is available for any particular resources beyond those described in representations previously received from the server.”

Page 39: Five Inconvenient Truths about REST

Example Message

39

<Hire id="h101442"> <CcuId>141705</CcuId> <EnclosingHireIds> <EnclosingHireId distance="1">a1</EnclosingHireId> </EnclosingHireIds> <OrgNo>123456789</OrgNo> <GlnLocation>1234567890123</GlnLocation> <StartDate>2013-10-09</StartDate> <EndDate>2013-11-08</EndDate> <Link href="/ccus/141705/hires/a1/hires/h101442" method="get" rel="self"/> <Link href="/ccus/141705" method="get" rel="Ccu"/> <Link href="/ccus/141705/hires/a1" method="get" rel="EnclosingHire"/></Hire>

Page 40: Five Inconvenient Truths about REST

Example Message

40

<Hire id="h101442"> <CcuId>141705</CcuId> <EnclosingHireIds> <EnclosingHireId distance="1">a1</EnclosingHireId> </EnclosingHireIds> <OrgNo>123456789</OrgNo> <GlnLocation>1234567890123</GlnLocation> <StartDate>2013-10-09</StartDate> <EndDate>2013-11-08</EndDate> <Link href="/ccus/141705/hires/a1/hires/h101442" method="get" rel="self"/> <Link href="/ccus/141705" method="get" rel="Ccu"/> <Link href="/ccus/141705/hires/a1" method="get" rel="EnclosingHire"/></Hire>

Page 41: Five Inconvenient Truths about REST

Example Message

41

<Hire id="h101442"> <CcuId>141705</CcuId> <EnclosingHireIds> <EnclosingHireId distance="1">a1</EnclosingHireId> </EnclosingHireIds> <OrgNo>123456789</OrgNo> <GlnLocation>1234567890123</GlnLocation> <StartDate>2013-10-09</StartDate> <EndDate>2013-11-08</EndDate> <Link href="/ccus/141705/hires/a1/hires/h101442" method="get" rel="self"/> <Link href="/ccus/141705" method="get" rel="Ccu"/> <Link href="/ccus/141705/hires/a1" method="get" rel="EnclosingHire"/></Hire>

199 out of 477 bytes(42%)

Page 42: Five Inconvenient Truths about REST

Example Message using Full HATEOAS

42

<Hire id="h101442"> <CcuId>141705</CcuId> <EnclosingHireIds> <EnclosingHireId distance="1">a1</EnclosingHireId> </EnclosingHireIds> <OrgNo>123456789</OrgNo> <GlnLocation>1234567890123</GlnLocation> <StartDate>2013-10-09</StartDate> <EndDate>2013-11-08</EndDate> <Link href="/ccus/141705/hires/a1/hires/h101442" method="get" rel="self"/> <Link href="/ccus/141705" method="get" rel="Ccu"/> <Link href="/ccus/141705/hires/a1" method="get" rel="EnclosingHire"/> <Link href="/organizations/123456789" method="get" rel="Organization"/> <Link href="/organizations/123456789/locations/1234567890123" method="get" rel="Location"/> <Link href="/ccus/141705/hires/a1/hires/h101442/documents" method="post" rel="Documents"/> <Link href="/ccus/141705/hires/a1/hires/h101442" method="put" rel="update"/> <Link href="/ccus/141705/hires/a1/hires/h101442/hires" method="post" rel="addHire"/></Hire>

620 out of 899 bytes(69%)

Page 43: Five Inconvenient Truths about REST

Martin Fowler on HATEOAS

43

“One obvious benefit of hypermedia controls is that it allows the server to change its URI scheme without breaking clients. As long as clients look up the ‘addTest’ link URI then the server team can juggle all URIs other than the initial entry points.”

http://martinfowler.com/articles/richardsonMaturityModel.html

Page 44: Five Inconvenient Truths about REST

Martin Fowler on HATEOAS

44

“A further benefit is that it helps client developers explore the protocol. The links give client developers a hint as to what may be possible next. It doesn't give all the information: both the “latest” and “cancel” controls point to the same URI – they need to figure out that one is a GET and the other a DELETE. But at least it gives them a starting point as to what to think about for more information and to look for a similar URI in the protocol documentation.”

http://martinfowler.com/articles/richardsonMaturityModel.html

Page 45: Five Inconvenient Truths about REST

Cost/Benefit of HATEOAS

What will change most often?● Behavior● Content● URIs

What's hard to refactor?● Behavior● Content● URIs

45

Page 46: Five Inconvenient Truths about REST

Example Message

46

<Hire id="h101442"> <CcuId>141705</CcuId> <EnclosingHireIds> <EnclosingHireId distance="1">b2</EnclosingHireId> <EnclosingHireId distance="2">a1</EnclosingHireId> </EnclosingHireIds> <OrgNo>123456789</OrgNo> <GlnLocation>1234567890123</GlnLocation> <StartDate>2013-10-09</StartDate> <EndDate>2013-11-08</EndDate> <Link href="/ccus/141705/hires/a1/hires/h101442" method="get" rel="self"/> <Link href="/ccus/141705" method="get" rel="Ccu"/> <Link href="/ccus/141705/hires/a1" method="get" rel="EnclosingHire"/> <Link href="/organizations/123456789" method="get" rel="Organization"/> <Link href="/organizations/123456789/locations/1234567890123" method="get" rel="Location"/> <Link href="/ccus/141705/hires/a1/hires/h101442/documents" method="post" rel="Documents"/> <Link href="/ccus/141705/hires/a1/hires/h101442" method="put" rel="update"/> <Link href="/ccus/141705/hires/a1/hires/h101442/hires" method="post" rel="addHire"/></Hire>

Page 47: Five Inconvenient Truths about REST

Example Message

47

<Hire id="h101442"> <CcuId>141705</CcuId> <EnclosingHireIds> <EnclosingHireId distance="1">b2</EnclosingHireId> <EnclosingHireId distance="2">a1</EnclosingHireId> </EnclosingHireIds> <OrgNo>123456789</OrgNo> <GlnLocation>1234567890123</GlnLocation> <StartDate>2013-10-09</StartDate> <EndDate>2013-11-08</EndDate> <Link href="/ccus/141705/hires/a1/hires/h101442" method="get" rel="self"/> <Link href="/ccus/141705" method="get" rel="Ccu"/> <Link href="/ccus/141705/hires/a1" method="get" rel="EnclosingHire"/> <Link href="/organizations/123456789" method="get" rel="Organization"/> <Link href="/organizations/123456789/locations/1234567890123" method="get" rel="Location"/> <Link href="/ccus/141705/hires/a1/hires/h101442/documents" method="post" rel="Documents"/> <Link href="/ccus/141705/hires/a1/hires/h101442" method="put" rel="update"/> <Link href="/ccus/141705/hires/a1/hires/h101442/hires" method="post" rel="addHire"/></Hire>

Page 48: Five Inconvenient Truths about REST

HATEOAS

48

● Uses a lot of bandwidth

● To avoid refactoring something that's easy to refactor

● Infrequent changes

● YAGNI (You aren't gonna need it)

Page 49: Five Inconvenient Truths about REST

INCONVENIENT TRUTH #5:

Hierarchical URIs will kill you in the end

49https://www.flickr.com/photos/grantmac/4192158869

Page 50: Five Inconvenient Truths about REST

50Fra: http://martinfowler.com/articles/richardsonMaturityModel.html

Richardson Maturity Model

Page 51: Five Inconvenient Truths about REST

Example Message

51

<Hire id="h101442"> <CcuId>141705</CcuId> <EnclosingHireIds> <EnclosingHireId distance="1">b2</EnclosingHireId> <EnclosingHireId distance="2">a1</EnclosingHireId> </EnclosingHireIds> <OrgNo>123456789</OrgNo> <GlnLocation>1234567890123</GlnLocation> <StartDate>2013-10-09</StartDate> <EndDate>2013-11-08</EndDate> <Link href="/ccus/141705/hires/a1/hires/h101442" method="get" rel="self"/> <Link href="/ccus/141705" method="get" rel="Ccu"/> <Link href="/ccus/141705/hires/a1" method="get" rel="EnclosingHire"/> <Link href="/organizations/123456789" method="get" rel="Organization"/> <Link href="/organizations/123456789/locations/1234567890123" method="get" rel="Location"/> <Link href="/ccus/141705/hires/a1/hires/h101442/documents" method="post" rel="Documents"/> <Link href="/ccus/141705/hires/a1/hires/h101442" method="put" rel="update"/> <Link href="/ccus/141705/hires/a1/hires/h101442/hires" method="post" rel="addHire"/></Hire>

Page 52: Five Inconvenient Truths about REST

Composition

● A hire on an asset cannot exist without the asset

● A subhire on a superhire cannot exist without the superhire

● A journey during a hire cannot exist without the hire

● Etc…

52https://www.flickr.com/photos/aspis7/5075169756

Page 53: Five Inconvenient Truths about REST

Example Hierarchical URI

53

/ccus/734975456/hires/13464654/hires/h101442/journeys/59267932/leg/93246452

Page 54: Five Inconvenient Truths about REST

Validation #1

54

/ccus/734975456/hires/13464654/hires/h101442/journeys/59267932/leg/93246452

Page 55: Five Inconvenient Truths about REST

Validation #2

55

/ccus/734975456/hires/13464654/hires/h101442/journeys/59267932/leg/93246452

Page 56: Five Inconvenient Truths about REST

Validation #3

56

/ccus/734975456/hires/13464654/hires/h101442/journeys/59267932/leg/93246452

Page 57: Five Inconvenient Truths about REST

Validation #4

57

/ccus/734975456/hires/13464654/hires/h101442/journeys/59267932/leg/93246452

Page 58: Five Inconvenient Truths about REST

Implied Access Control and Confidentiality Constraints?

58

/ccus/734975456/hires/13464654/hires/h101442/journeys/59267932/leg/93246452

Page 59: Five Inconvenient Truths about REST

What's the Alternative?

/ccus/734975456

/hires/13464654

/hires/h101442

/journeys/59267932

/leg/93246452

59https://www.flickr.com/photos/aspis7/5075169756

Page 60: Five Inconvenient Truths about REST

The things I wish I knew

a couple of years ago…

60

Page 61: Five Inconvenient Truths about REST

INCONVENIENT TRUTH #1:

GET calls are never nullipotent

61https://www.flickr.com/photos/grantmac/4192158869

Page 62: Five Inconvenient Truths about REST

INCONVENIENT TRUTH #2:

HTTP Verbs ≠ “REST Verbs”

62https://www.flickr.com/photos/grantmac/4192158869

Page 63: Five Inconvenient Truths about REST

INCONVENIENT TRUTH #3:

HTTP Response Codes ≠ “REST Response Codes”

63https://www.flickr.com/photos/grantmac/4192158869

Page 64: Five Inconvenient Truths about REST

INCONVENIENT TRUTH #4:

HATEOAS YAGNI⇒

64https://www.flickr.com/photos/grantmac/4192158869

Page 65: Five Inconvenient Truths about REST

INCONVENIENT TRUTH #5:

Hierarchical URIs will kill you in the end

65https://www.flickr.com/photos/grantmac/4192158869

Page 66: Five Inconvenient Truths about REST

Thank You for Your Attention!

66

Contact information:

@filipvanlaenen

[email protected] / [email protected]

https://no.linkedin.com/in/filipvanlaenen

http://www.slideshare.net/filipvanlaenen/