SpringBoot HATEOAS
Hypermedia-Driven RESTful Web Service
HATEOAS๋ maturity model(์ฑ์๋)์ ๋ํด์ lv3์ ํด๋นํ๊ณ , ๋๋ถ๋ถ์ ๋ค lv2์ ํด๋นํด์ ์งํ๋๊ณ ์๋ค.
๋ ๋ฒจ2๋ ๋ฉ์๋์ ์ด๋ค ๊ฒ์ ์งํํ ๊ฒ์ธ์ง ์ค์ ํด์ฃผ๊ณ , url์๋ ์์์ ์ง์ด๋ฃ์ด์ฃผ๋ฉฐ, JSON๋ฐฉ์์ ํ์ฉํ๋ ๋ฐฉ์์ด๋ค.
๋ ๋ฒจ3์ ๋ ๋ฒจ2์๋ค๊ฐ ์ถ๊ฐ์ ์ธ ๋งํฌ๋ฅผ ๋ฃ์ด์ฃผ๋ ๋ฐฉ์์ด๋ค. ์๋ต์๋ค๊ฐ JSON+HAL(๋งํฌ๋ฅผ ์ถ๊ฐ)
Hypermedia As The Engine Of Application State(HATEOAS)
hypermedia = data + links(ํ์ฌ resource์์ ์ํํ ์ ์๋ ์ก์ )
์ฐ๊ด๋ ์ ๋ณด๋ค๋ ๋งํฌ์ ๋ด์์ ์๋ตํ๋ ๋ฐฉ์
์ ํ๋ฆฌ์ผ์ด์ ์ ํด๋ผ์ด์ธํธ์๊ฒ API์ ๋ํ ๊ฐ์ด๋๋ฅผ ํด์ผํ๋ค๋ ์์น์ ๊ฐ์ง๊ณ ์๋ค. โ ์ด๊ฑด ๋ค์์ผ๋ก ์ด๋ ํ step์ด ๊ฐ๋ฅํ์ง๋ฅผ ํ์ํจ์ผ๋ก์จ ๊ฐ๋ฅํ๋ค
์ต์ข ๋ชฉ์ : ํด๋ผ์ด์ธํธ์ ์๋ฒ๋ฅผ ๋ถ๋ฆฌ์์ผ์ ๊ฐ๊ฐ ๋ฐ๋ก ์งํํ ์ ์๊ฒ ํ๋ค
HAL(Hypertext Application Language) Model
JSON + Link(relation + href) + embedded resource
์ฅ์
URL์ ๋ง์๊ป ๋ฐ๊ฟ๋ ๊ด์ฐฎ๋ค,
API์ ์ฒ์ ์ ๊ทผํ๋ ์ฌ๋์๊ฒ ์ข์ ์๋ด์๊ฐ ๋ ์ ์๋ค.
client - server๊ฐ ์์กด์ฑ์ ์ค์ด๊ณ ์๋ก ๋ ๋ฆฝ์ ์ผ๋ก ๋ฐ๊ฟ
์ฌ์ฉํ๊ธฐ ์ํด์ pom.xml์์
spring-boot-starter-hateoas ์ ์ถ๊ฐํด์ฃผ์ด์ผํจ
WebMvcLinkBuilder
์๋๋ Link link = new Linkt("http://~"); ์ด๋ ๊ฒ ๋ง๋ค์ด์ผํ์ง๋ง
WebMvcLinkBuilder์ ์ฌ์ฉํ๊ฒ๋๋ฉด ๋งํฌ๋ฅผ ํ๋์ฝ๋ฉํด์ ์ฌ์ฉํ์ง ์๊ณ ์์ฑํ๋๊ฒ์ด ๊ฐ๋ฅํ๋ค.
RepresentationModel
EntityModel(single resource) โ PagedModel โ CollectionModel(multiple resource) โ RepresentationModel
Entity๋ฅผ ๊ธฐ๋ฐ์ผ๋กํด์ representationalModel์ ๋ง๋ค๊ฒ๋๋๋ฐ ๋๊ฐ์์๋ ์๊ณ ์ผ๋ถ๋ง ๋ค์ด๊ฐ์์์๋ ์๋ค.
Presentation Layer์๋ DTO(data, getter, setter, ์์ฑ์ ์ ๋๋ง์ผ๋ก ๊ตฌ์ฑ๋์ด์๊ณ , ๋น์ง๋์ค ๋ก์ง์ ๋ฐ๋ก ์ถ๊ฐํ์ง ์๋๋ค)
Bussiness Layer์๋ Domain(entity)
Representational model assembler
entity๋ฅผ representational model(DTO)๋ก ๋ณํํด์ฃผ๋ ํจ์์ด๋ค.
RepresentationModelAssembler๋ผ๋ ์ธํฐํ์ด์ค๋ฅผ ์ด๋ฏธ ์ ๊ณต์ค์ ์๋ค. ์ด๊ฒ์ implements ํด์ ๋ง๋ RepresentationModelAssemblerSupport ํด๋์ค๋ฅผ ์์๋ฐ์์ ์ฌ์ฉํ๋ฉด ๋๋ค!!!
์์๋ฐ๊ณ
toModel(), toCollectionModel() ์ overrideํด์ ์ฌ์ฉ
๋ด๋ถ ๊ตฌํ
instantiateModel()์ ํตํด์ ์ธ์คํด์ค๋ฅผ ๋ง๋ค์ด์ฃผ๊ณ
set์ผ๋ก entity์ ์๋ ์์ฑ๋ค์ ๋ฃ์ด์ฃผ๊ณ
๋งํฌ๋ฅผ ์ถ๊ฐํ๊ธฐ ์ํด์ add(linkTo(methodOn().getActorById)))์ ๋ฃ์ด์ค
Optional<Type> : ๊ฐ์ด ์์ผ๋ฉด ๊ฐ์ ์ฃผ๋๋ฐ, ๋ง์ฝ null๊ฐ์ด๋ฉด exception์ด ๋ฐ์ํ๊ฒ ๋๋๋ฐ ์ด๊ฒ์ ๋ฐฉ์งํด์ค
.map(actorModelAssembler::toModel).map(ResponseEntity::ok).orElse(ResponseEntity.notFound().build());
Last updated
Was this helpful?