Dlaczego 99% firm, które tworzą API RESTowe kłamie?

58
DLACZEGO 99% FIRM, KTÓRE TWORZĄ API RESTOWE KŁAMIE? / Bartek Andrzejczak @baandrzejczak

Transcript of Dlaczego 99% firm, które tworzą API RESTowe kłamie?

Page 1: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

DLACZEGO 99% FIRM, KTÓRE TWORZĄAPI RESTOWE KŁAMIE?

/ Bartek Andrzejczak @baandrzejczak

Page 3: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

AGENDAGeneza kłamstwaCo to jest HATEOAS?Jak ważny jest HATEOAS?Czy HATEOAS jest mi potrzebny?HATEOAS od strony serweraHATEOAS od strony klienta

Page 4: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

MOŻE POWTÓRZYMY ANGIELSKI?

Page 5: Dlaczego 99% firm, które tworzą API RESTowe kłamie?
Page 6: Dlaczego 99% firm, które tworzą API RESTowe kłamie?
Page 7: Dlaczego 99% firm, które tworzą API RESTowe kłamie?
Page 9: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

CZYM WŁAŚCIWIE JEST REST?This chapter introduces and elaborates the

Representational State Transfer (REST)architectural style for distributed hypermedia

systems (...)

(...) a style is a named set of constraints onarchitectural elements that induces the set of

properties desired of the architecture.

"Architectural Styles and the Design ofNetwork-based Software Architectures"

Roy T. Fielding

Page 10: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

OGRANICZENIA NARZUCANE PRZEZ RESTPodział klient-serwerBezstanowość serweraCacheJednolity interfejs

Identyfikacja zasobówManipulacja zasobami przez reprezentacjeSamoopisujące się wiadomościHATEOAS

Podział na warstwyCode-on-demand (Opcjonalne)

Page 11: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

HYPERMEDIA AS THE ENGINE OFAPPLICATION STATE

Page 12: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

Role, artefakty, zdarzenia oraz reguły Scrumasą niezmienne i choć możliwe jest

wykorzystanie tylko wybranych jegoelementów, wynikiem takiego postępowania

nie będzie Scrum. Scrum istnieje tylko wswojej pełnej postaci i sprawdza się doskonale

w roli ramy dla innych technik, metodyk czypraktyk.

Scrum Guide

Page 13: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

JAK WAŻNY JEST HATEOAS?In order to obtain a uniform interface,

multiple architectural constraints are neededto guide the behavior of components. REST is

defined by four interface constraints:identification of resources; manipulation of

resources through representations; self-descriptive messages; and, hypermedia as theengine of application state. These constraints

will be discussed in Section 5.2.

"Architectural Styles and the Design ofNetwork-based Software Architectures"

Roy T. Fielding

Page 14: Dlaczego 99% firm, które tworzą API RESTowe kłamie?
Page 15: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

The name “Representational State Transfer” is intended toevoke an image of how a well-designed Web application

behaves:a network of web pages (a virtual state-machine)where the user progresses through the application byselecting links (state transitions)resulting in the next page (representing the next state of theapplication) being transferred to the user and rendered fortheir use

Page 16: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

CO DAJE NAM HATEOAS?

Page 17: Dlaczego 99% firm, które tworzą API RESTowe kłamie?
Page 18: Dlaczego 99% firm, które tworzą API RESTowe kłamie?
Page 19: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

KIEDY HATEOAS JEST STRATĄ CZASU?Brak wyraźnego flow aplikacjiCRUDMałe API

Page 20: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

ZALETYSterowanie przepływem danych w aplikacjiSterowanie dostępnymi podzasobamiLuźniejsze związanie serwera i klientaDodatkowa dokumentacja API (jednak niewystarczająca)

Page 21: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

WADYWięcej pracyWięcej transferuBrak ekspertów w temacieTworzenie API dla nieistniejącego klienta

Page 22: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

DLA JAKIEGO KLIENTA NADAJE SIĘ HATEOAS?

Page 23: Dlaczego 99% firm, które tworzą API RESTowe kłamie?
Page 24: Dlaczego 99% firm, które tworzą API RESTowe kłamie?
Page 25: Dlaczego 99% firm, które tworzą API RESTowe kłamie?
Page 26: Dlaczego 99% firm, które tworzą API RESTowe kłamie?
Page 27: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

FORMAT LINKÓW

HTML<a href="http://swapi.co/api/films/1/">A New Hope</a>

Page 28: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

JSON API "name": "Luke Skywalker", "height": "1.72 m", "mass": "77 Kg", "hair_color": "Blond", "links": "species": "self": "http://swapi.co/api/species/1/", "all": "http://swapi.co/api/species/"

Page 29: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

PAYPAL API "name": "Luke Skywalker", "height": "1.72 m", "links": [ "href": "http://swapi.co/api/people/1/", "rel": "self", "method": "GET" , "href": "http://swapi.co/api/species/1/", "rel": "species", "method": "GET" ]

Page 30: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

VERTICALRESPONSE API "name": "Luke Skywalker", "height": "1.72 m", "mass": "77 Kg", "hair_color": "Blond", "links": "self": "url": "http://swapi.co/api/people/1/" , "homeworld": "url": "http://swapi.co/api/planets/1/"

Page 31: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

HYPERTEXT APPLICATION LANGUAGE (HAL) "name": "Luke Skywalker", "height": "1.72 m", "mass": "77 Kg", "hair_color": "Blond", "_links": "self": "href": "http://swapi.co/api/people/1/", "title": "Luke Skywalker" , "http://swapi.co/api/rels/species": "href": "http://swapi.co/api/species/1/", "title": "Human"

Page 32: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

HYPERTEXT APPLICATION LANGUAGE (HAL) "_links": "self": "href": "/" , "curies": [ "name": "ht", "href": "http://haltalk.herokuapp.com/rels/rel", "templated": true ], "ht:users": "href": "/users"

Page 33: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

JSON-LD "name": "Luke Skywalker", "height": "1.72 m", "mass": "77 Kg", "hair_color": "Blond", "@self": "http://swapi.co/api/people/1/", "@species": "http://swapi.co/api/species/1/",

Page 34: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

NAGŁÓWKI HTTPLink: <http://swapi.co/api/species/1/>; rel="species"

Page 35: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

HATEOAS NA SERWERZE

Page 36: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

JERSEY DECLARATIVE LINKING

NAJPROSTSZY PRZYKŁAD@Path("/people")public class PeopleResource @GET public List<Person> list() ... @GET @Path("/id") public Person get(@PathParam("id") String personId) return new PeopleRepository().find(personId);

public class Person public String name; @InjectLink(resource=PeopleResource.class) public URI self;

"name": "Luke Skywalker", "self": "http://swapi.co/api/people"

Page 37: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

PARAMETRY ŚCIEŻEK@Path("/people/id")public class PersonResource ...public class Person public String name; @InjectLink( resource=PlanetResource.class, bindings= @Binding("$resource.homeworldId") ) public URI homeworld; @JsonIgnore public String homeworldId;

"name": "Luke Skywalker", "homeworld": "http://swapi.co/api/planets/1"

Page 38: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

STAŁE ŚCIEŻKIpublic class Root @InjectLink("/films", rel="films") public URI films;

"films": "http://swapi.co/api/films"

Page 39: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

LINKI W NAGŁÓWKACH@InjectLinks( value=@InjectLink("planets/$resource.homeworldId"), rel="homeworld")public class Person public String name; @JsonIgnore public String homeworldId;

HTTP 200 OKAllow: GET, HEAD, OPTIONSContent­Type: application/jsonVary: AcceptLink: <http://swapi.co/api/planets/1>; rel="homeworld"

"name": "Luke Skywalker"

Page 40: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

PLUSYWybór pomiędzy linkami w nagłówkach i wreprezentacjach

MINUSYBrak możliwości przesyłania tylko niektórychlinkówSilne połączenie reprezentacji z zasobamiAnnotation hell

Page 41: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

JAX-RS 2.0

Tylko imperatywna konstrukcja linków.@Path("/people/id")public class PersonResource @GET public Response get(@PathParam("id") String personId) return Response .ok(new PeopleRepository().find(personId)) .links(Link.fromResource(PersonResource.class) .rel("self").build(personId)) .build();

HTTP 200 OKContent­Type: application/jsonLink: <http://swapi.co/api/people/1>; rel="self"

Page 42: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

Ścieżki można pobierać z metod...@Path("/people/id")public class PersonResource @GET public Response get(@PathParam("id") String personId) return Response .ok(new PeopleRepository().find(personId)) .links(Link .fromMethod(PersonResource.class, "films") .rel("films").build(personId)) .build();

@GET @Path("/films") public Response films() ...

HTTP 200 OKContent­Type: application/jsonLink: <http://swapi.co/api/people/1/films>; rel="films"

Page 43: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

...lub hardcodować@GETpublic Response get(@PathParam("id") String personId) Person person = new PeopleRepository().find(personId); String fatherId = person.findFather(); return Response .ok() .links(Link .fromPath("/people/id") .rel("father").build(fatherId)) .build();

HTTP 200 OKContent­Type: application/jsonLink: <http://swapi.co/api/people/darthVader>; rel="father"

"name": "Luke Skywalker"

Page 44: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

PLUSYBrak ingerencji w klasy reprezentacjiImplementacja przez wiele różnych frameworków

MINUSYPłaska struktura linkówNagłówek trudniej jest analizować niżreprezentację

Page 45: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

SPRING-HATEOAS

Aby dodawać linki do klasy, musi ona rozszerzać klasęResourceSupport - linki staną się częścią reprezentacji.

public class Person extends ResourceSupport public String name; public String height; public String mass; public String hair_color;

Page 46: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

Linki dodajemy bezpośrednio do reprezentacjiimport static org.springframework.hateoas.mvc.ControllerLinkBuilder.*;

@Controllerpublic class PersonController @RequestMapping("/people/id") @ResponseBody public HttpEntity<Person> get(@PathVariable("id") String personId) Person person = new PeopleRepository().find(personId); person.add( linkTo(methodOn(PersonController.class).get(personId)) .withSelfRel() ); return new ResponseEntity<Person>(person, HttpStatus.OK);

Page 47: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

Wynik: "name": "Luke Skywalker", "height": "1.72 m", "mass": "77 Kg", "hair_color": "Blond", "_links": "self": "href": "http://swapi.co/api/people/1"

Page 48: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

PLUSYMinimalna ingerencja w klasy reprezentacjiMożliwość zagnieżdżania linkówObsługa różnych formatów linkówWsparcie JAX-RS

MINUSYNarastająca logika w kontrolerach, w przypadkulinkowania bardziej skomplikowanych struktur(np. kolekcji)

Page 49: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

HATEOAS W KLIENCIE

Page 50: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

JAVA (JAX-RS)

Linki w reprezentacjach "name": "Luke Skywalker", "links": "homeworld": "uri": "http://swapi.co/api/planets/1"

final Person table = target.request().get(Person.class);

URI homeworldURI = table.getLinks().getHomeworld().getUri();WebTarget homeworldTarget = client.target(homeworldURI);

Page 51: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

Linki w nagłówkachHTTP 200 OKContent­Type: application/jsonLink: <http://swapi.co/api/planets/1>; rel="homeworld"Link: <http://swapi.co/api/species/1>; rel="species"

"name": "Luke Skywalker"

final Response response = target.request().get();

URI homeworldURI = response.getLink("homeworld").getUri();URI speciesURI = response.getLink("species").getUri();

Page 52: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

JAVASCRIPT (ANGULARJS)

Linki w reprezentacjach "name": "Luke Skywalker", "links": "father": "uri": "http://swapi.co/api/people/2"

var personResource = $resource("/api/people/:personId");

var luke = personResource.query(personId: 1, function () var lukesFather = $resource(luke.links.father) .query(null, function () console.log(lukesFather); ););

Page 53: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

Linki w nagłówkachHTTP 200 OKContent­Type: application/jsonLink: <http://swapi.co/api/people/2>; rel="father"

"name": "Luke Skywalker"

var personResource = $resource("/api/people/:personId");

var luke = personResource.query(personId: 1, function () var lukesFather = firstPerson.resource("father") .query(null, function () console.log(lukesFather); ););

Page 54: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

Link: </people>; rel="people"; actions="[ 'name':'add','method':'POST', 'name':'list','method':'GET' ]"

$http.get("/").success( function (root) var peopleList = root.links.people.list(); root.links.people.add( "name": "Darth Vader", "height": "1.8" ); );

https://github.com/bandrzejczak/bpm-console-gui

https://github.com/bandrzejczak/bpm-console-rest

Page 55: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

PODSUMOWANIEHATEOASMaszyna stanówRosnące wsparcie bibliotek

Page 56: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

SWAPI.CO

Page 57: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

PYTANIA?

Page 58: Dlaczego 99% firm, które tworzą API RESTowe kłamie?

DZIĘKI!