Primary focus of this presentation is on the hypermedia as the engine of application state (HATEOAS) and how HTTP APIs may benefit from it. Provides sneak peek into HAL media type & gives an overview of hypermedia support in Java tools (JAX-RS / HalBuilder and Spring HATEOAS) along with practical suggestions for server-side design of hypermedia API. Also includes quick overview of Richardson Maturity Model based on a set of examples, current API trends.
8. Hypermedia
REST
8
Level 0 / SOAP-like
1. Single URI endpoint: /bookings
2. Single HTTP method: POST
3. Action in payload
4. «RPC»-like
5. Uses HTTP as transport, not app protocol
6. Does not use mechanics of the Web
Flickr SOAP &
XML-RPC APIs
9. Hypermedia
REST
9
Level 2 - Make a Booking
POST /hotels/cosmopolite/rooms/std/bookings
{
«check-in»: «2014-11-23»,
«check-out»: «2014-12-01»,
«breakfast»: true
}
request
200 OK
{
«id»: «123»,
«room-id»: «kyiv:cosmopolite:std»,
«check-in»: …
}
response
11. URI Template Contract
Hypermedia
REST
11
URL Methods
/hotels GET = retrieve hotels
/hotels/{id} GET = retrieve hotel
/hotels/{id}/rooms/{roomId}/bookings POST = create booking
/bookings GET = retrieve bookings
/bookings/{id}
GET = retrieve booking!
PATCH = update booking!
PUT = replace booking!
DELETE = update booking
/bookings/{id}/payment POST = pay
12. Level 2 / CRUD-like
1. Many URIs, many verbs
2. Use mechanics of the Web (partially)
3. NO hypermedia
Hypermedia
REST
12
Amazon S3
Twitter API
Google APIs
15. Hypermedia
REST
15
Resource State
What is stored on the server
(beyond session)
16. Hypermedia
REST
16
Application State
Where you ARE in the
interaction / session
Pending Confirmed
Served
create
update
rejected
cancel Cancelled
"live"
confirmed
Rejected
update
delete
18. Hypermedia
REST
18
link
{
«take-a-rest:hotel»: {
«href»: «http://localhost:8080/api/hotels/2»
}
}
‣ URI - identifies a resource with which the
consumer can interact to progress the application
protocol
‣ rel - contains semantic markup (=> verb, headers,
structure of the payload)
22. Client
Hypermedia
REST
22
if (booking.links.has("payment")) {
// draw payment button / UI
}
Hypermedia client
does NOT break, because it does
NOT expect link to be always
available
28. Hypermedia
REST
28
profit
• API: explorable & self-documented
• Client:
• No URL construction
• No domain logic replication
• Less coupling
• Server:
• Transparent resource relocation
• Easier versioning & evolvability
29. «REST doesn’t eliminate the need for a
clue. What REST does is concentrate that
need for prior knowledge into readily
standardizable forms. That is the essential
distinction between data-oriented and
Hypermedia
REST
29
control-oriented integration.»
Roy T. Fielding, 2008
30. «... It has value because it is far easier to
standardize representation and relation
types than it is to standardize objects
and object-specific interfaces ...»
Hypermedia
REST
Roy T. Fielding, 2008
30
31. Hypermedia
REST
31
cons
• efficiency
• tooling
• understanding
by developer community
34. «A REST API should spend almost all of its
descriptive effort in defining the media
type(s) used for representing resources and
driving application state, or in defining
Hypermedia
REST
34
extended relation names and/or
hypertext-enabled mark-up for existing
standard media types.»
Roy T. Fielding, 2008
35. Hypermedia Factors / Control Data Support
Hypermedia
REST
35
IANA Link Relations
Name Description RFC
self Conveys an identifier for the link's context. RFC4287
first An IRI that refers to the furthest preceding resource in a series of
resources. RFC5988
last An IRI that refers to the furthest following resource in a series of
resources. RFC5988
up Refers to a parent document in a hierarchy of documents. RFC5988
item The target IRI points to a resource that is a member of the collection
represented by the context IRI. RFC6573
collection The target IRI points to a resource which represents the collection
resource for the context IRI. RFC6573
edit Refers to a resource that can be used to edit the link's context. RFC5023
prev/previous Indicates that the link's context is a part of a series, and that the previous
in the series is the link target. HTML5
next Indicates that the link's context is a part of a series, and that the next in
the series is the link target. HTML5
36. Hypermedia Factors / Control Data Support
Hypermedia
REST
36
IANA Link Relations
Name Description RFC
create-form The target IRI points to a resource where a submission form can be
obtained. RFC6861
edit-form The target IRI points to a resource where a submission form for editing
associated resource can be obtained. RFC6861
payment Indicates a resource where payment is accepted RFC5988
latest-version Points to a resource containing the latest (e.g., current) version of the
context. RFC5829
profile Identifying that a resource representation conforms to a certain profile,
without affecting the non-profile semantics of the resource
representation.
RFC6906
search Refers to a resource that can be used to search through the link's
context and related resources. OpenSearch
index Refers to an index. HTML4
about Refers to a resource that is the subject of the link's context. RFC6903
help Refers to context-sensitive help. HTML5
48. id not necessarily exposed in data:
links encode it to preserve lookup strategy
Hypermedia
REST
http://localhost:8080/api/bookings/12345
48
Integration Domain
(external, REST API)
@Getter
@Setter
public class BookingRepresentation {
!
private LocalDate checkIn;
private LocalDate checkOut;
private boolean includeBreakfast;
private BigDecimal price;
..private List<Link> links;
!
}
49. Core Domain ≠
Integration Domain
Hypermedia
REST
49
• Different clients
• Different reasons to change
• Different rate of change
• IMPORTANT!
• Do not bridge Core domain to Integration domain
(exposing it via REST API directly) to avoid coupling
issues!
52. Embedded / Full Resource
• Representations usually require different hypertext
(both data and links)
• Provide separate assembler classes for embedded
and full resource representations!
• Allow property expansion for granularity control:
Hypermedia
REST
52
/api/bookings/12345?props=checkIn,checkOut
53. Hypermedia
REST
53
Tooling Support
1. Media Type
• Representation Model
• Assembly
2. Link Construction
3. Documentation
68. • XML support via halbuilder-xml
• JAX-RS support via halbuilder-jaxrs
• Scala support via halbuilder-scala
• Representation reader API
• Modular
• Open for customization
• Agnostic to web framework (JAX-RS / Spring / etc.)
Hypermedia
REST
68
69. • setting «self» link:
RepresentationFactory.newRepresentation(String/URI)
• field mapping: Representation.withFields
• mapping delegation: Representation.withRepresentable
• serialization options: pretty print, null stripping,
collating links, etc.
• custom Jackson’s ObjectMapper configuration available
via custom RepresentationFactory
• option to serialize directly to java.io.Writer
• link rel validation
Hypermedia
REST
69
70. Hypermedia
REST
70
Link Construction: How?
based on the request:
scheme server port
{
"_links": {
"take-a-rest:booking": {
"href": "http://localhost:8080/api/bookings/12345"
}
},
…
}
root URL rel. resource URL
based on configuration:
71. @Controller
@RequestMapping("/bookings")
public class BookingController {
!
..@RequestMapping(value = "/{id}", method = RequestMethod.GET)
..public HttpEntity<BookingRepr> retrieveById(@PathVariable Long id) {
....BookingRepr representation = …;
....// add links
....return new HttpEntity<BookingRepr>(representation);
..}
!
}
Hypermedia
HATEOAS
REST
71
Controller
/api/bookings
/api/bookings/{id}
72. Not a Go
Hypermedia
HATEOAS
REST
72
representation.add(
....new Link("http://localhost:8080/api/bookings/" + id)
);
- does not respect request protocol, host and port
- may not URL-escape id properly if it is a String
- breaks if root URL changes
- breaks if controller URL mappings change