Share
Embed
RESTful Hypermedia APIs
This is a presentation about REST, Hypermedia (HATEOAS), different representation formats like HAL or Siren. Also Java implementations like HalBuilder, Spring HATEOAS and Spring Data Rest are discussed.
Kai Toedter
April 10, 2018
Transcript
44 slides
-
Who am I? Principal Key Expert at Siemens Building
Technologies Web Technology Fan Open Source Lover E-mail: [email protected] Twitter: twitter.com/kaitoedter Blog: toedter.com/blog 4/9/2018 2 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. -
Show Hands! 4/9/2018 © Kai Tödter, Licensed under a Creative
Commons Attribution 4.0 International License. 3 -
Outline REST Basics HATEOAS Hypermedia Examples
API Documentation Demos & Live Coding Conclusion 4/9/2018 4 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. -
4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution
4.0 International License. 5 REST Basics -
What is REST? Stands for Representational State Transfer
Is a Software Architecture Style was introduced and defined in 2000 by Roy T. Fielding in his doctoral dissertation REST != CRUD via HTTP 4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 6 -
REST Architectural Constraints Client-Server Stateless Cacheable
Layered system Code on demand (optional) Uniform interface (see next slide) 4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 7 -
Uniform Interface Identification of resources Manipulation of resources
through their representations Create => HTTP POST Read => HTTP GET Update => HTTP PUT, HTTP PATCH Delete => HTTP DELETE Self-descriptive messages Hypermedia as the engine of application state (HATEOAS) 4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 8 -
Richardson Maturity Model Level 3: Hypermedia Controls Level 2: HTTP
Verbs Level 1: Resources Level 0: The Swamp of POX 4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 9 See http://martinfowler.com/articles/richardsonMaturityModel.html -
Hypermedia APIs for Services are like Web Pages with Links
for Humans 4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 10 -
4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution
4.0 International License. 11 Existing Hypermedia Representations -
Hypermedia Representations HAL - http://stateless.co/hal_specification.html Siren - https://github.com/kevinswiber/siren
Collection+JSON - http://amundsen.com/media- types/collection/format/ UBER - https://rawgit.com/mamund/media-types/master/uber- hypermedia.html ALPS - http://alps.io/ Hydra - http://www.markus-lanthaler.com/hydra/ JSON-LD - http://json-ld.org/ json:api - http://jsonapi.org/ Mason - https://github.com/JornWildt/Mason 4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 12 -
HAL Is for Hypertext Application Language Was created
by Mike Kelly Representations for both JSON and XML Very popular 4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 13 -
HAL Structure 4/9/2018 © Kai Tödter, Licensed under a Creative
Commons Attribution 4.0 International License. 14 Plain old JSON Properties Links Plain old JSON Properties Links Plain old JSON Properties Links … Embedded Resources Embedded Resources Embedded Resources -
HAL Example { "id":1, "text":"hello all!", "_links": { "self": {
"href":"http://localhost:8080/chatty/api/messages/1" } }, "_embedded": { "author": { "id":"toedter_k" } } } 4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 15 -
Siren Developed by Kevin Swiber Similar to HAL
Provides more mechanisms E.g. Actions A bit more complex 4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 16 -
Siren Example { "class": [ "message" ], "properties": { "id":
1, "text": "hello all!", }, "entities": [ { "class": [ "author" ], "properties": { "id": "toedter_k" } } ], "links": [ { "rel": [ "self" ], "href": "http://localhost:8080/chatty/api/messages/1" }, ] } 4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 17 -
Siren Action Example "actions": [ { "name": "add-item", "title": "Add
Item", "method": "POST", "href": "http://api.x.io/orders/42/items", "type": "application/x-www-form-urlencoded", "fields": [ { "name": "orderNumber", "type": "hidden", "value": "42" }, { "name": "productCode", "type": "text" }, { "name": "quantity", "type": "number" } ] } ] 4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 18 -
Java Implementations 4/9/2018 © Kai Tödter, Licensed under a Creative
Commons Attribution 4.0 International License. 19 -
Java Implementations HAL HalBuilder Spring HATEOAS
halarious HyperExpress hate SlimPay HAPI client Katharsis … 4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 20 Siren Siren4j HalBuilder (Siren Extension) SirenJeeni … -
siren4j Link selfLink = LinkBuilder.newInstance() .setRelationship(Link.RELATIONSHIP_SELF) .setHref("/self/link") .build(); Entity result
= EntityBuilder.newInstance() .setEntityClass("test") .addProperty("foo", "hello") .addProperty("number", 1) .addLink(selfLink) .build(); 4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 21 -
siren4j Annotations @Siren4JEntity(name = "video", uri = "/videos/{id}") public class
VideoResource extends BaseResource { private String id; private String name; … 4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 22 -
HalBuilder @GET @Produces(RepresentationFactory.HAL_JSON) public String getApi(@Context UriInfo uriInfo) { Representation
repr = representationFactory .newRepresentation() .withNamespace("chatty","http://docu.chatty.com/{rel}"); .withLink("chatty:users", createUriFromResource(baseURI, UserResource.class)) return repr.toString(RepresentationFactory.HAL_JSON); } 4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 23 -
JSON Result { _links: { curies: { href: "http://docu.chatty.com/{rel}", name:
"chatty", templated: true }, chatty:users: { href: "http://localhost:8080/chatty/api/users" } } } 4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 24 -
Spring Spring Boot Spring Data REST Spring
HATEOAS 4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 25 -
Domain Classes with Project Lombok @Data @Entity @NoArgsConstructor public class
User { @Id private String id; private String fullName; private String email; @OneToMany(mappedBy="author", cascade=CascadeType.ALL) List<ChatMessage> messages; } 4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 26 -
Spring Data REST: Repository @RepositoryRestResource( collectionResourceRel = "users", path =
"users") interface UserRepository extends PagingAndSortingRepository<User, String> { } 4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 27 -
Spring Data REST: Repository (2) @RepositoryRestResource( exported = false )
interface UserRepository extends PagingAndSortingRepository<User, String> { } 4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 28 -
Spring Data Rest: JSON Result { _links: { self: {
href: "http://localhost:8080/chatty/api/users{?page,size,sort}", templated: true } }, _embedded: { users: [ { fullName: "Jane Doe", email: "[email protected]", _links: { self: { href: "http://localhost:8080/chatty/api/users/doe_ja" }, … 4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 29 -
JavaScript Implementations HAL backbone.hal gomoob/backbone.hateoas RePoChO/backbone.hateoas
halbert halberd JS HAL hateoas-client hyperagent.js Traverson Ember.js Data HAL Adapter HALSON hal-body koa-hal angular-hal angular-hy-res halacious for node/hapi rest.js (from the cujo toolkit) angular-hypermedia 4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 30 Siren Node-siren Backbone.Siren AngularHypermedia angular-hy-res … -
Robust Clients Start from main API Find link
relations through defined contracts Follow Links For navigation For possible “actions” => Clients are robust regarding changes in link URIs 4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 31 -
API Documentation 4/9/2018 © Kai Tödter, Licensed under a Creative
Commons Attribution 4.0 International License. 32 -
API Documentation Tools Swagger (OpenAPI) Spring REST Docs
RAML (RESTful API Modeling Language) … 4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 33 -
Swagger 4/9/2018 © Kai Tödter, Licensed under a Creative Commons
Attribution 4.0 International License. 34 -
Swagger + Hypermedia Pros High Adoption Good
tooling Active community Cons It’s URI-Centric Not suitable for hypermedia and links OpenAPI v3 introduced links, but they are not sufficient for Hypermedia doc It’s has a pretty big footprint (many libs) Not recommended for the documentation of Level 3 REST APIs 4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 35 -
Spring REST Docs Write Tests for the API documentation
Tests will fail if real behavior and documented behavior are out of sync! Include generated AsciiDoc snippets in manually written AsciiDoc API documentation Supports Hypermedia well 4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 36 -
Spring REST Docs Example Test @Test public void shouldDocumentBuildInfo() throws
Exception { this.mockMvc.perform(get("/api/buildinfo")) .andExpect(status().isOk()) .andDo(document("build-info-get-example", responseFields( fieldWithPath("version").description("The version of this build"), fieldWithPath("timeStamp").description("The creation timestamp"), fieldWithPath("_links.self").description("link to this resource") ))); } 4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 37 -
Spring REST Docs Example Result 4/9/2018 © Kai Tödter, Licensed
under a Creative Commons Attribution 4.0 International License. 38 -
Live Demos Sources: https://github.com/toedter/chatty Demo: https://chatty42.herokuapp.com HAL Browser: https://chatty42.herokuapp.com/api/ 4/9/2018
© Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 39 -
Controversial Discussion Are we there yet? RESTistential Crises
http://www.infoq.com/news/2014/03/rest-at- odds-with-web-apis DHH, Getting hyper about hypermedia apis https://signalvnoise.com/posts/3373-getting- hyper-about-hypermedia-apis 4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 40 -
Conclusion 4/9/2018 © Kai Tödter, Licensed under a Creative Commons
Attribution 4.0 International License. 41 RESTful Web Services + Hypermedia --------------------------------------------- Works very well together -
4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution
4.0 International License. 42 Discussion -
Links siren4j: https://code.google.com/p/siren4j/ HalBuilder: https://github.com/HalBuilder Spring Data
REST: http://projects.spring.io/spring-data-rest/ Spring REST Docs: http://projects.spring.io/spring-restdocs Project Lombok: http://projectlombok.org/ 4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 43 -
License This work is licensed under a Creative Commons
Attribution 4.0 International License. See http://creativecommons.org/licenses/by/4.0/ 4/9/2018 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 44