Implementing Spring HATEOAS to display related links

2025. 3. 3. 18:42Spring Microservice

📌 Spring HATEOAS를 활용한 연관 링크 표시하기

🔹 Spring HATEOAS란?

HATEOAS(Hypermedia as the Engine of Application State)는 API가 리소스에 대한 관련 링크를 포함하여 클라이언트가 응답을 기반으로 다음 액션을 쉽게 수행할 수 있도록 하는 원칙입니다.

Spring HATEOAS는 이를 지원하는 경량 프로젝트로, API 응답에 관련 링크를 추가하여 서비스 탐색성을 높일 수 있도록 도와줍니다.
필수 기능은 아니지만, API의 가이드 역할을 수행하며 전체 리소스에 대한 경로를 제공하기 때문에 마이크로서비스 환경에서 유용하게 활용될 수 있습니다. 💡

🎯 Spring HATEOAS 적용 예제

다음은 License 리소스에 대한 HATEOAS 적용 결과입니다.

"_links": {
  "self": {
    "href": "http://localhost:8080/v1/organization/optimaGrowth/license/0235431845"
  },
  "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/0235431845"
  }
}

위와 같이 self, createLicense, updateLicense, deleteLicense 등의 링크를 포함하여 API의 탐색성을 높일 수 있습니다. 🚀

🔧 Spring HATEOAS 적용 방법

1️⃣ 의존성 추가

Spring Boot 프로젝트에서 HATEOAS를 사용하려면 spring-boot-starter-hateoas 의존성을 추가해야 합니다.

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>

2️⃣ License 모델 클래스 수정

HATEOAS를 적용하려면, License 모델이 RepresentationModel<License> 를 상속받도록 변경해야 합니다.

package com.optimagrowth.license.model;

import org.springframework.hateoas.RepresentationModel;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@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> 를 상속하면 API 응답에 링크를 추가할 수 있습니다.

3️⃣ LicenseController에 링크 추가

HATEOAS를 적용하여 LicenseController 클래스에서 getLicense() 메서드가 관련 링크를 포함하도록 수정합니다.

//import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
//import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*;

@RequestMapping(value = "/{licenseId}", method = RequestMethod.GET)
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() 메서드를 사용하여 self, createLicense, updateLicense, deleteLicense 등의 링크를 추가했습니다.
linkTo()methodOn() 을 활용하여 컨트롤러의 메서드에 대한 링크를 동적으로 생성했습니다.
withSelfRel() : 해당 리소스를 가리키는 self 링크를 설정합니다.
withRel("createLicense") : 생성(create) 링크 추가
withRel("updateLicense") : 수정(update) 링크 추가
withRel("deleteLicense") : 삭제(delete) 링크 추가

📌 WebMvcLinkBuilder 활용

Spring HATEOAS의 WebMvcLinkBuilder 는 컨트롤러의 경로를 자동으로 생성해주므로, 직접 URL을 하드코딩할 필요 없이 유지보수성이 향상됩니다.

import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*;

위와 같이 WebMvcLinkBuilderimport 하여 linkTo(methodOn(클래스명.class).메서드()) 형태로 쉽게 활용할 수 있습니다. 💡

🏆 결과 확인

HATEOAS 적용 후, /v1/organization/optimaGrowth/license/{licenseId} 엔드포인트를 호출하면 다음과 같이 링크가 포함된 JSON 응답을 확인할 수 있습니다.

GET http://localhost:8080/v1/organization/optimaGrowth/license/0235431845

 

{
    "id": 260,
    "licenseId": "0235431845",
    "description": "Software product",
    "organizationId": "optimaGrowth",
    "productName": "Ostock",
    "licenseType": "full",
    "_links": {
        "self": {
            "href": "http://localhost:8080/v1/organization/optimaGrowth/license/0235431845"
        },
        "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/0235431845"
        }
    }
}

이제 클라이언트는 API 응답을 기반으로 생성, 수정, 삭제 링크를 쉽게 탐색할 수 있습니다. 🔗

🔥 정리

✅ Spring HATEOAS는 API 응답에 연관 링크를 제공하여 탐색성을 높이는 기술
spring-boot-starter-hateoas 의존성 추가 후 RepresentationModel<T> 를 상속하여 활용
WebMvcLinkBuilder 를 사용하여 컨트롤러 메서드에 대한 동적 링크 생성 가능
✅ 응답을 기반으로 클라이언트가 다음 액션을 쉽게 수행할 수 있도록 가이드 제공

 

💡 Spring HATEOAS를 활용하면 API가 자체적인 문서 역할을 하며, RESTful 서비스의 직관성과 활용도가 높아집니다! 🚀

 

이제 API를 설계할 때 HATEOAS를 적용하여 더 명확하고 직관적인 RESTful API 를 만들어보세요! 😉