스프링 HATEOAS(Hypermedia As The Engine Of Application State) 는 애플리케이션 상태 엔진인 하이퍼미디어를 의미하며 HATEOAS원칙(해당 리소스와 관련된 링크를 표시하는)을 준수하는 API를 생성하는 작은 프로젝트다. 이 원칙에 따르면 API는 각 서비스 응답과 함께 가능한 다음 단계 정보도 제공하며, 클라이언트를 다음 단계로 가이드할 수 있어야 한다. 이 프로젝트는 핵심 또는 필수 기능은 아니지만 주어진 리소스의 모든 API에 대한 완전한 가이드를 원한다면 훌륭한 방안이다.
스프링 HATEOAS를 사용하면 리소스 표현 모델의 링크에 대한 모델 클래스를 빠르게 생성할 수 있으며, 스프링 MVC 컨트롤러 메서드에 대한 특정 링크를 생성하는 링크 빌더 API도 제공한다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
<version>2.7.4</version>
</dependency>
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.hateoas.RepresentationModel;
@Getter @Setter @ToString
public class License extends RepresentationModel<License> {
private int id;
private String licenseId;
private String description;
private String organizationId;
private String productName;
private String licenseType;
}
RepresentationModel<License>는 License 모델 클래스에 링크를 추가할 수 있게 한다.
@GetMapping(value = "/{licenseId}")
public ResponseEntity<License> getLicense(@PathVariable("organizationId") String organizationId, @PathVariable("licenseId") String licenseId){
License license = licenseService.getLicense(licenseId, organizationId);
license.add(linkTo(methodOn(LicenseController.class)
.getLicense(organizationId, license.getLicenseId()))
.withSelfRel(),
linkTo(methodOn(LicenseController.class)
.createLicense(organizationId, license, null))
.withRel("createLicense"),
linkTo(methodOn(LicenseController.class)
.updateLicense(organizationId, license))
.withRel("updateLicense"),
linkTo(methodOn(LicenseController.class)
.deleteLicense(organizationId, license.getLicenseId()))
.withRel("deleteLicense"));
return ResponseEntity.ok(license);
}
add()는 RepresentationModel 클래스 메서드이며, linkTo() 메서드는 LicenseController 클래스를 검사해서 루트 매핑을 얻고, methodOn() 메서드는 대상 메서드에 더미 호출을 수행하여 메서드 매핑을 가졍온다.
{
"id": 697,
"licenseId": "2222222",
"description": "Software product",
"organizationId": "optimaGrowth",
"productName": "Ostock",
"licenseType": "full",
"_links": {
"self": {
"href": "http://localhost:8080/v1/organization/optimaGrowth/license/2222222"
},
"createLicense": {
"href": "http://localhost:8080/v1/organization/optimaGrowth/license"
},
"updateLicense": {
"href": "http://localhost:8080/v1/organization/optimaGrowth/license"
},
"deleteLicense": {
"href": "http://localhost:8080/v1/organization/optimaGrowth/license/2222222"
}
}
}
GET 호출하면 나오는 결과