Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Spring HATEOAS
Search
Dai Yamasaki
November 15, 2019
Programming
0
1k
Spring HATEOAS
JSUG勉強会 2019その10 SpringOne Platform 2019報告会
Dai Yamasaki
November 15, 2019
Tweet
Share
Other Decks in Programming
See All in Programming
Hotwire or React? ~アフタートーク・本編に含めなかった話~ / Hotwire or React? after talk
harunatsujita
1
110
Macとオーディオ再生 2024/11/02
yusukeito
0
340
Snowflake x dbtで作るセキュアでアジャイルなデータ基盤
tsoshiro
2
500
ActiveSupport::Notifications supporting instrumentation of Rails apps with OpenTelemetry
ymtdzzz
1
180
受け取る人から提供する人になるということ
little_rubyist
0
190
推し活の ハイトラフィックに立ち向かう Railsとアーキテクチャ - Kaigi on Rails 2024
falcon8823
6
2.7k
Importmapを使ったJavaScriptの 読み込みとブラウザアドオンの影響
swamp09
4
1.3k
現場で役立つモデリング 超入門
masuda220
PRO
15
3.1k
リアーキテクチャxDDD 1年間の取り組みと進化
hsawaji
1
200
Generative AI Use Cases JP (略称:GenU)奮闘記
hideg
0
190
C++でシェーダを書く
fadis
6
4k
【Kaigi on Rails 2024】YOUTRUST スポンサーLT
krpk1900
1
310
Featured
See All Featured
What's in a price? How to price your products and services
michaelherold
243
12k
Adopting Sorbet at Scale
ufuk
73
9.1k
YesSQL, Process and Tooling at Scale
rocio
168
14k
Facilitating Awesome Meetings
lara
49
6.1k
4 Signs Your Business is Dying
shpigford
180
21k
How to train your dragon (web standard)
notwaldorf
88
5.7k
A Philosophy of Restraint
colly
203
16k
Rebuilding a faster, lazier Slack
samanthasiow
79
8.7k
Being A Developer After 40
akosma
86
590k
Thoughts on Productivity
jonyablonski
67
4.3k
Done Done
chrislema
181
16k
The Pragmatic Product Professional
lauravandoore
31
6.3k
Transcript
4QSJOH)"5&0"4 %BJ:BNBTBLJ 5BHCBOHFST *OD
Who am I •Dai Yamasaki •Born to develop •I k6o
dislike Tokyo
r,BNFIBNFIB*** ΧΠέΞΦϦ l6B.BVLF&BPLBb⒖JOBJLB1POP ʢʮͷੜ໋ʢ㲈ओݖʣਖ਼ٛʹΑͬͯӬଓ͢Δʯʣz
Spring HATEOAS - Hypermedia APIs with Spring https://www.youtube.com/watch?v=o4cc6KzNrpI&list=PLAdzTan_eSPRlQ8t4TU5c-AB4SHV939M6&index=46
Who use HATEOAS
Migration script 0.x $ ./migrate-to-1.0.sh Migrating Spring HATEOAS references to
1.0 for files : *.java Adapting ./src/main/java/… … Done! https://github.com/spring-projects/spring-hateoas/tree/master/etc
Hypermedia -JOL -JOL -JOL -JOL
REST ख़ • Level 0 ҰͭͷURLͱҰͭͷHTTPϝιου • Level 1 ҟͳΔURLͱҰͭͷHTTPϝιου
• Level 2 ҟͳΔURLͱҟͳΔHTTPϝιου • Level 3 APIͷϨεϙϯεʹϋΠύʔϦϯΫใΛ࣋ͭ
Hypermedia + REST { "orderID":…, "productID”:…, "quantity":…, "orderValue":…, "_links":[ {
"rel":"customer", "href":"...", }, { "rel":"self", "href":"...", }] }
Hypermedia As The Engine Of Application State H A T
E O A S HATEOAS
Hypermedia + REST { "orderID":…, "productID”:…, "quantity":…, "orderValue":…, "_links":[ {
“rel":"cancel", "href":"...", }, { "rel":"self", "href":"...", }] }
Why HATEOAS • ϦϯΫ͕Θ͔Ε CRUD ͕Ͱ͖Δ • ϏδωεϩδοΫͷྲྀग़Λආ͚Δ ΫϥΠΞϯτϦϯΫͷ༗ແͰஅ •
ϖʔδϯάͷදݱʹ໎Θͳ͍ { "orderID":…, "productID”:…, "quantity":…, "orderValue":…, "_links":[ { “rel":"cancel", "href":"...", }, { "rel":"self", "href":"...", }] }
Spring HATEOAS
Representation Model
Representation Model
Links & Affordance
ΞϑΥʔμϯεʢaffordanceʣͱɺ ڥ͕ಈʹରͯ͠༩͑Δʮҙຯʯͷ͜ͱͰ͋Δɻ ΞϝϦΧͷ֮৺ཧֶऀδΣʔϜζɾJɾΪϒιϯʹΑΔޠͰ͋Γɺ ੜଶޫֶɺੜଶ৺ཧֶͷجఈత֓೦Ͱ͋Δɻ ʮ༩͑Δɺఏڙ͢Δʯͱ͍͏ҙຯͷӳޠ afford ͔ΒΒΕͨɻ Affordances
Affordance https://www.amazon.co.jp/%E3%82%B5%E3%83%B3%E3%82%A2%E3%83%BC%E3%83%88-%E3%81%8A%E3%82%82%E3%81%97%E3%82%8D%E9%A3%9F%E5%99%A8-4%E6%96%87%E5%AD%97%E3%83%9D%E3%83%AA%E3%82%B7%E3%83%BC- %E3%83%9E%E3%82%B0%E3%82%AB%E3%83%83%E3%83%97-SAN1858/dp/B003NEPOTW
Links & Affordances { "name": "Dai Yamasaki", "role": "Developer", "_links":
{ "self": { "href": “/employees/0" }, "employees": { "href": "/employees" } }, "_templates": { "default": { "method": "put", "properties": [ { "name": "name", "required": true }, { "name": "role" } ] }, "partiallyUpdateEmployee": { "method": "patch", "properties": [ { "name": "name" }, { "name": "role" } …
Links & Affordances @GetMapping("/employees/{id}") public EntityModel<Employee> findOne(@PathVariable Integer id) {
Employee employee = employeeRepository.findOneById(id); // ࣗࣗ "self" ͷϦϯΫΛ࡞ WebMvcEmployeeController controller = methodOn(WebMvcEmployeeController.class); Link findOneLink = linkTo(controller.findOne(id)).withSelfRel(); // Affordance ΛؚΊͨใΛฦ͢ return new EntityModel<>( employee, findOneLink .andAffordance( afford(controller.updateEmployee(null, id))) .andAffordance( afford(controller.partiallyUpdateEmployee(null, id)))); }
4FQBSBUFSFTPVSDF Links & Affordances { "_links": { "my-app:payment": {...}, "curies":
[ { "name": "my-app", "href": "http://hoge.com/docs/{rel}", "templated": true }] } } IUUQNZBQQDPNEPDTQBZNFOU
*OMJOFSFTPVSDF { ... "_templates": { "default": { "method": "put", "properties":
[{ "name": "number", "regex": "[0-9]{16}" }] } } } Links & Affordances
.FEJB5ZQFT
5SBWFSTPO @Test void traverson() { Traverson traverson = new Traverson(baseUri,
MediaTypes.HAL_JSON); ParameterizedTypeReference<EntityModel<Actor>> typeReference = new ParameterizedTypeReference<EntityModel<Actor>>() {}; EntityModel<Actor> result = traverson.follow("movies", "movie", “actor") .toObject(typeReference); assertThat(result.getContent().name) .isEqualTo("Dwayne Douglas Johnson"); }
5SBWFSTPO { "_links": { "movie": { "href": "http://localhost:8080/movies/63e0c973-1606-4fe7-b4e3-0de03d2e0c06" } }
} { "title": "Fast & Furious Presents: Hobbs & Shaw", "_links": { "actor": { "href": "http://localhost:8080/actors/f58ebb17-abd8-48fb-b06c-5a912251631c" } } } { "name": "Dwayne Douglas Johnson" } NPWJFT EntityModel<Actor> result = traverson.follow("movies", "movie", “actor") .toObject(typeReference); NPWJF BDUPS
0UIFS • RepresentationModelAssembler • I18N support • LinkRelationProvider
5IBOLT