2024. 12. 11. 12:19ㆍSpring Framework/Spring HATEOAS
📌 _links란?
_links
는 RESTful API에서 하이퍼미디어(HATEOAS)를 지원하기 위해 사용되는 JSON 필드로,
클라이언트가 API 응답을 통해 동적으로 리소스를 탐색할 수 있도록 도와줍니다.
Spring HATEOAS에서는 RepresentationModel
을 활용해 _links
필드를 자동으로 생성할 수 있습니다.
🎯 1. _links의 개념
🔹 REST API에서 리소스 간 탐색을 가능하게 함
🔹 HATEOAS(Hypermedia as the Engine of Application State)의 핵심 요소
🔹 각 리소스가 어떤 동작을 수행할 수 있는지 명확하게 제공
🔹 클라이언트가 URL을 직접 구성하지 않고도 API를 동적으로 탐색 가능
📌 2. _links의 역할과 구조
✅ 예제 API 응답 (_links
포함)
{
"id": 1,
"licenseId": "456",
"description": "Software Product",
"organizationId": "123",
"productName": "Ostock",
"licenseType": "full",
"_links": {
"self": {
"href": "http://localhost:8080/v1/organization/123/license/456"
},
"update": {
"href": "http://localhost:8080/v1/organization/123/license/456"
},
"delete": {
"href": "http://localhost:8080/v1/organization/123/license/456"
},
"organization": {
"href": "http://localhost:8080/v1/organization/123"
},
"all-licenses": {
"href": "http://localhost:8080/v1/organization/123/licenses"
}
}
}
✅ _links
안에 여러 개의 링크가 포함됨
✅ self 링크: 현재 리소스를 참조
✅ update 링크: 해당 리소스를 업데이트할 수 있는 경로
✅ delete 링크: 해당 리소스를 삭제할 수 있는 경로
✅ organization 링크: 해당 라이선스가 속한 조직 정보 제공
✅ all-licenses 링크: 조직에 속한 모든 라이선스를 조회하는 경로
🏗 3. Spring HATEOAS에서 _links 자동 생성
Spring Boot와 Spring HATEOAS를 사용하면 _links
필드를 자동으로 생성할 수 있습니다.
📌 Step 1: Spring HATEOAS 의존성 추가
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
✅ spring-boot-starter-hateoas
를 추가하면 _links를 자동으로 생성할 수 있는 기능 제공
📌 Step 2: HATEOAS를 지원하는 모델 정의
import org.springframework.hateoas.RepresentationModel;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class License extends RepresentationModel<License> { // ✅ RepresentationModel 상속
private int id;
private String licenseId;
private String description;
private String organizationId;
private String productName;
private String licenseType;
}
✅ RepresentationModel<T>
을 상속하면 해당 객체에 HATEOAS 링크 추가 가능
📌 Step 3: 컨트롤러에서 _links 추가
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping(value = "v1/organization/{organizationId}/license")
public class LicenseController {
@GetMapping(value = "/{licenseId}")
public ResponseEntity<EntityModel<License>> getLicense(
@PathVariable("organizationId") String organizationId,
@PathVariable("licenseId") String licenseId) {
License license = new License();
license.setId(1);
license.setLicenseId(licenseId);
license.setOrganizationId(organizationId);
license.setDescription("Software Product");
license.setProductName("Ostock");
license.setLicenseType("full");
// ✅ Self 링크 추가
Link selfLink = WebMvcLinkBuilder.linkTo(
WebMvcLinkBuilder.methodOn(LicenseController.class)
.getLicense(organizationId, licenseId))
.withSelfRel();
// ✅ 업데이트 링크 추가
Link updateLink = WebMvcLinkBuilder.linkTo(
WebMvcLinkBuilder.methodOn(LicenseController.class)
.updateLicense(organizationId, license))
.withRel("update");
// ✅ 삭제 링크 추가
Link deleteLink = WebMvcLinkBuilder.linkTo(
WebMvcLinkBuilder.methodOn(LicenseController.class)
.deleteLicense(organizationId, licenseId))
.withRel("delete");
// ✅ 조직 링크 추가
Link orgLink = WebMvcLinkBuilder.linkTo(
WebMvcLinkBuilder.methodOn(OrganizationController.class)
.getOrganization(organizationId))
.withRel("organization");
// ✅ 모든 라이선스 조회 링크 추가
Link allLicensesLink = WebMvcLinkBuilder.linkTo(
WebMvcLinkBuilder.methodOn(LicenseController.class)
.getAllLicenses(organizationId))
.withRel("all-licenses");
return ResponseEntity.ok(EntityModel.of(license, selfLink, updateLink, deleteLink, orgLink, allLicensesLink));
}
}
✅ HATEOAS 링크 추가하는 과정
selfLink
→ 현재 리소스를 가리키는 self 링크 생성updateLink
→ 해당 리소스를 업데이트하는 링크 생성deleteLink
→ 해당 리소스를 삭제하는 링크 생성orgLink
→ 조직 정보를 조회하는 링크 생성allLicensesLink
→ 조직의 모든 라이선스를 조회하는 링크 생성
⚙️ 4. _links의 다양한 활용 예제
✅ 1) Self 링크만 포함
"_links": {
"self": {
"href": "http://localhost:8080/v1/organization/123/license/456"
}
}
🔹 현재 리소스(license 456
)를 다시 조회하는 경로 제공
✅ 2) CRUD 연산을 지원하는 링크
"_links": {
"self": {
"href": "http://localhost:8080/v1/organization/123/license/456"
},
"update": {
"href": "http://localhost:8080/v1/organization/123/license/456"
},
"delete": {
"href": "http://localhost:8080/v1/organization/123/license/456"
}
}
🔹 클라이언트가 API 응답을 보고 직접 경로를 구성하지 않아도 동작 가능
🔹 업데이트와 삭제를 위한 API 링크 제공
✅ 3) 관련 리소스를 탐색하는 링크
"_links": {
"self": {
"href": "http://localhost:8080/v1/organization/123/license/456"
},
"organization": {
"href": "http://localhost:8080/v1/organization/123"
},
"all-licenses": {
"href": "http://localhost:8080/v1/organization/123/licenses"
}
}
🔹 해당 라이선스가 속한 조직을 조회할 수 있는 organization
링크 추가
🔹 조직 내 모든 라이선스를 조회하는 all-licenses
링크 추가
🎉 5. 결론
✅ _links
는 REST API에서 하이퍼미디어(HATEOAS)를 적용하여 클라이언트가 동적으로 API를 탐색할 수 있도록 지원
✅ Spring HATEOAS를 활용하면 _links
를 쉽게 추가하고 유지보수성을 높일 수 있음
✅ Self 링크뿐만 아니라, 관련 리소스 및 CRUD 연산을 위한 링크도 함께 제공하면 API 사용성이 극대화됨 🚀
'Spring Framework > Spring HATEOAS' 카테고리의 다른 글
HATEOAS(Hypermedia as the Engine of Application State) (0) | 2025.03.03 |
---|---|
WebMvcLinkBuilder (0) | 2024.12.11 |
self 링크 (0) | 2024.12.09 |
EntityModel (0) | 2024.12.09 |
RepresentationModel (0) | 2024.12.09 |