Share
Embed
Hello REST API: What can I do next?
In this presentation, Kai shows how to use hypermedia to create REST APIs that do not only provide data but also information about what to do next. This can be in the form of hyperlinks for navigating and describing actions that can be performed on the REST resources. As an example representation, HAL-Forms is used, an extension of the popular HAL format. Another topic is the Affordances API of the current Spring HATEOAS (Hypermedia as the Engine of Application State).
Kai Toedter
November 07, 2019
Transcript
54 slides
-
Who am I? Principal Key Expert at Siemens Smart
Infrastructure Web Technology Fan Open Source Lover E-mail: [email protected] Twitter: @kaitoedter 11/9/2019 2 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. -
Show Hands! 11/9/2019 © Kai Tödter, Licensed under a Creative
Commons Attribution 4.0 International License. 3 -
Outline HATEOAS? Links Affordances Demos &
Live Coding Conclusion 11/9/2019 4 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. -
HATEOAS Is for “Hypermedia As The Engine Of Application
State” Very hard to pronounce Key concept of REST 11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 5 -
“With HATEOAS, a client interacts with a network application whose
application servers provide information dynamically through hypermedia. A REST client needs little to no prior knowledge about how to interact with an application or server beyond a generic understanding of hypermedia.” 11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 6 Wikipedia Source: https://en.wikipedia.org/wiki/HATEOAS -
“When I say Hypertext, I mean … The simultaneous presentation
of information and controls such that the information becomes the affordance through which the user obtains choices and selects actions.” 11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 7 Roy Fielding Source: http://roy.gbiv.com/talks/200711_REST_ApacheCon.pdf -
Richardson Maturity Model Level 3: Hypermedia Controls Level 2: HTTP
Verbs Level 1: Resources Level 0: The Swamp of POX 11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 8 Source: http://martinfowler.com/articles/richardsonMaturityModel.html -
Spring HATEOAS Spring basic framework for REST with Hypermedia
support Overhaul in version 1.0.0 Supports generic Hypermedia API Supports Representations like HAL, HAL-FORMS, UBER, Collection+JSON, … https://docs.spring.io/spring-hateoas/docs/current- SNAPSHOT/reference/html/ 11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 9 -
11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution
4.0 International License. 10 Links -
Links Essential for hypermedia In REST: How to
navigate to a REST resource Link semantic/name is called link relation The relation between a REST resource and the target REST resource Links are well known from HTML, like <a href="url">link text</a> 11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 11 -
Links in Spring HATEOAS Link link = new Link("/my-url");
A link automatically has a self relation Link link = new Link("/my-url", "my-rel"); A link with my-rel relation 11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 12 -
Link Relations Many Link relations are standardized by IANA
IANA = Internet Assigned Numbers Authority https://www.iana.org/assignments/link- relations/link-relations.xhtml Examples: self, item, next, last, … Recommendation: Before creating a custom name for a link relation, look up the IANA list! 11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 13 -
11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution
4.0 International License. 14 Root API -
api.github.com 11/9/2019 © Kai Tödter, Licensed under a Creative Commons
Attribution 4.0 International License. 15 { "current_user_url": "https://api.github.com/user", "current_user_authorizations_html_url": "https://github.com/settings/connections/applications{/client_id}", "authorizations_url": "https://api.github.com/authorizations", "code_search_url": "https://api.github.com/search/code?q={query}{&page,per_page,sort,order}", "commit_search_url": "https://api.github.com/search/commits?q={query}{&page,per_page,sort,order}", "emails_url": "https://api.github.com/user/emails", "emojis_url": "https://api.github.com/emojis", "events_url": "https://api.github.com/events", "feeds_url": "https://api.github.com/feeds", "followers_url": "https://api.github.com/user/followers", "following_url": "https://api.github.com/user/following{/target}", "gists_url": "https://api.github.com/gists{/gist_id}", "hub_url": "https://api.github.com/hub", "issue_search_url": "https://api.github.com/search/issues?q={query}{&page,per_page,sort,order}", "issues_url": "https://api.github.com/issues", "keys_url": "https://api.github.com/user/keys", "notifications_url": "https://api.github.com/notifications", "organization_repositories_url": "https://api.github.com/orgs/{org}/repos{?type,page,per_page,sort}", … } -
Movies Root API { "_links": { "self": { "href": "http://localhost:8080/api"
}, "movies": { "href": "http://localhost:8080/api/movies{?size,page}", "templated": true }, "directors": { "href": "http://localhost:8080/api/directors{?size,page}", "templated": true } } } 11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 16 -
Links are Great For providing navigation to useful other
REST resources For providing domain knowledge to the REST clients, so that they don’t have to compute domain state on there own 11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 17 -
11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution
4.0 International License. 18 Representation Models -
Representation Models REST => Representational State Transfer Manipulation
of resources through their representations Domain Model != Representation Model Spring HATEOAS provides RepresentationModel abstraction 11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 19 -
Spring HATEOAS RepresentationModel RepresentationModel Root class, for REST
item resourses CollectionModel For REST collection resources EntityModel Convenient wrapper for converting a domain model into a representation model PagedModel Addition to CollectionModel for paged collections 11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 20 -
Domain Model Example @Data @Entity @NoArgsConstructor public class Director {
@Id @GeneratedValue private Long id; private String name; @ManyToMany(fetch = FetchType.EAGER) private List<Movie> movies = new ArrayList<>(); public Director(String name) { this.name = name; } … } 11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 21 -
Representation Model Example @Data public class DirectorRepresentationModel extends RepresentationModel<DirectorRepresentationModel> {
private String name; public DirectorRepresentationModel(Director director) { this.name = director.getName(); add(linkTo(methodOn(DirectorController.class) .findOne(director.getId())).withSelfRel()); for (Movie movie : director.getMovies()) { add(linkTo(methodOn(MovieController.class) .findOne(movie.getId())) .withRel("movies") .withTitle(movie.getTitle())); } } } 11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 22 -
11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution
4.0 International License. 23 HAL Image Source: http://wallpoper.com/images/00/26/43/92/hal-9000_00264392.jpg -
HAL Is for Hypertext Application Language Created by
Mike Kelly Representations for both JSON and XML Very popular & very simple Spec: https://tools.ietf.org/html/draft-kelly- json-hal-08 11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 24 -
HAL Structure 11/9/2019 © Kai Tödter, Licensed under a Creative
Commons Attribution 4.0 International License. 25 Plain old JSON Properties Links Plain old JSON Properties Links Plain old JSON Properties Links … Embedded Resources Embedded Resources Embedded Resources -
HAL Example { "name": "Ridley Scott", "_links": { "self": {
"href": "https://movies-demo.org/api/directors/89", }, "movies": [ { "href": "https://movies-demo.org/api/movies/93", "title": "Alien" }, … ] } } 11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 26 -
URI Templates A URI Template is used for describing
a range of URIs through variable expansion Defined in https://tools.ietf.org/html/rfc6570 Example: https://mymovies.org/api/movies{?size,page} 11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 27 -
URI Templates in Spring HATEOAS UriTemplate template = UriTemplate.of("/movies") .with(new
TemplateVariable("page", REQUEST_PARAM)) .with(new TemplateVariable("size", REQUEST_PARAM)); => /movies{?page,size} 11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 28 -
HAL URI Templates Example { "_links": { "self": { "href":
"https://movies-demo.org/api" }, "movies": { "href": "https://movies-demo.org/api/movies{?size,page}", "templated": true }, "directors": { "href": "https://movies-demo.org/api/directors{?size,page}", "templated": true } } } 11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 29 -
11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution
4.0 International License. 30 Paging Image Source: https://de.freeimages.com/photo/open-book-1417485 -
Example: Paging (1) Paging is useful to partition large
result sets If you had to write a frontend for paging, you need information about: Number of all pages Current page Page size Info about first, previous, next, last page URLs 11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 31 -
Example: Paging (2) If a (frontend) client only gets
current page, page size, number of all pages It has to decide when to enable/disable First, Prev, Next, Last buttons It has to compute all the data fetching URLs for above buttons 11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 32 -
Example: Server-side Paging with Links "_links": { "next": { "href":
"http://movie-demo.org/api/movies?page=1&size=10" }, "last": { "href": "http://movie-demo.org/api/movies?page=14&size=10" } } Important: NO links for first and prev => extra semantics! Client has just to interpret the links to create the UI 11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 33 -
Movies Paging Demo 11/9/2019 © Kai Tödter, Licensed under a
Creative Commons Attribution 4.0 International License. 34 -
Paging Client with Vue.js <ul class="pagination"> <li :class="{'page-item':true, 'disabled':!links.first}"> <a
class="page-link" href="#" aria-label="First" v-on:click="getMovies(links.first.href)"> <span aria-hidden="true">«</span> <span class="sr-only">First</span> </a> </li> <li :class="{'page-item':true, 'disabled':!links.prev}"> <a class="page-link" href="#" aria-label="Previous" v-on:click="getMovies(links.prev.href)"> <span aria-hidden="true">‹</span> <span class="sr-only">Previous</span> </a> </li> 11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 35 -
11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution
4.0 International License. 36 Affordances -
“ The affordances of the environment are what it offers
… what it provides or furnishes, either for good or ill. The verb 'to afford' is found in the dictionary, but the noun 'affordance' is not. I have made it up.” James J. Gibson The Ecological Approach to Visual Perception (1986) 11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 37 -
Affordances With Affordances, possible actions on a REST resource
(or Link relation) can be described in more detail, e.g. What can you do with a REST resource? Create, Update, Delete, … Which parameters are mandatory or optional How would (internationalized) labels be displayed in a user interface … 11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 38 -
Spring HATEOAS Affordances Example public MovieRepresentationModel toModel(Movie movie) { Link
selfLink = linkTo(methodOn(MovieController.class) .findOne(movie.getId())).withSelfRel(); final Affordance updateAffordance = afford(methodOn(MovieController.class) .updateMovie(null, movie.getId())); final Affordance deleteAffordance = afford(methodOn(MovieController.class) .deleteMovie(movie.getId())); return new MovieRepresentationModel(movie, selfLink .andAffordance(updateAffordance) .andAffordance(deleteAffordance)); } © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 39 -
11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution
4.0 International License. 40 HAL-FORMS Image Source: http://wallpoper.com/images/00/26/43/92/hal-9000_00264392.jpg Shutdown! Restart -
HAL-FORMS Designed to provide forms support for HAL
Created by Mike Amundsen _templates for possible actions on self link Spec: https://rwcbook.github.io/hal-forms/ 11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 41 -
“The HAL-FORMS media type design follows many of the HAL
media type conventions. For this reason, HAL-FORMS "looks like HAL." However, it is important to keep in mind that HAL-FORMS is not the same as HAL — the two should not be thought of as interchangeable in any way.” 11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 42 Mike Amundsen Source: https://rwcbook.github.io/hal-forms/ -
Rendering with HAL-FORMS (1) "_templates": { "default": { "title": null,
"method": "put", "contentType": "", "properties": [ { "name": "imdbId", "prompt": "IMDB Id", "required": true }, … © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 43 -
Rendering with HAL-FORMS (2) "_templates": { "default": { … },
"deleteMovie": { "title": null, "method": "delete", "contentType": "", "properties": [] } } © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 44 -
HAL Explorer https://github.com/toedter/hal-explorer Easily integratable through WebJar and
spring-data-rest-hal-explorer dependency Supports HAL, HAL-FORMS and Spring JSON Schema Supports custom request headers Supports theming and responsive design 11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 45 -
HAL Explorer 11/9/2019 © Kai Tödter, Licensed under a Creative
Commons Attribution 4.0 International License. 46 -
Spring HATEOAS Internationalization Resource bundle: rest-messages.properties Examples
Movie._templates.updateMovie.title=Change Movie Movie.year._prompt=Release Year Reacts on Accept-Language HTTP header Accept-Language: de-DE,de;q=0.9,en;q=0.8,en-US;q=0.7 Would return German if there is a _de resource bundle 11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 47 -
Movie Details with Affordances (EN) 11/9/2019 © Kai Tödter, Licensed
under a Creative Commons Attribution 4.0 International License. 48 -
Movie Details with Affordances (DE) 11/9/2019 © Kai Tödter, Licensed
under a Creative Commons Attribution 4.0 International License. 49 -
Client “Domain vs Protocol” Knowledge No Hypermedia Links Affordances 11/9/2019
© Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 50 Domain Knowledge Protocol Knowledge Client Effort & Robustness -
Demo + Live Coding 11/9/2019 © Kai Tödter, Licensed under
a Creative Commons Attribution 4.0 International License. 51 -
11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution
4.0 International License. 52 Discussion -
Links Movies Hypermedia Demo: https://github.com/toedter/movies-demo Spring HATEOAS: https://github.com/spring-projects/spring-
hateoas 11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 53 -
License This work is licensed under a Creative Commons
Attribution 4.0 International License. See http://creativecommons.org/licenses/by/4.0/ 11/9/2019 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 54