WebMvcLinkBuilder

2024. 12. 11. 12:22Spring Framework/Spring HATEOAS

📌 WebMvcLinkBuilder란?

WebMvcLinkBuilderSpring HATEOAS에서 하이퍼미디어 링크를 생성하는 유틸리티 클래스입니다.
REST API에서 클라이언트가 동적으로 리소스를 탐색할 수 있도록 self, update, delete 등의 링크를 쉽게 추가하는 데 사용됩니다.

🎯 1. WebMvcLinkBuilder의 역할

Spring MVC 컨트롤러의 메서드를 기반으로 동적으로 링크를 생성
RESTful API에서 HATEOAS(하이퍼미디어)를 지원하는 핵심 클래스
클라이언트가 API 엔드포인트를 쉽게 탐색할 수 있도록 도움
Spring Boot 애플리케이션에서 URI를 직접 하드코딩하지 않고 자동으로 생성 가능

📌 2. WebMvcLinkBuilder 사용법

📌 Step 1: Maven 의존성 추가

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

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

✅ Spring Boot 3.x부터는 spring-hateoas가 Jakarta EE를 기반으로 변경되었음.
✅ Spring Boot 2.x에서는 spring-boot-starter-hateoas 대신 spring-hateoas 사용 가능.

📌 Step 2: WebMvcLinkBuilder로 Self 링크 생성

self 링크를 생성하는 기본적인 방법입니다.

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

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("/api/licenses")
public class LicenseController {

    @GetMapping("/{licenseId}")
    public ResponseEntity<EntityModel<License>> getLicense(@PathVariable String licenseId) {

        License license = new License(licenseId, "Software License", "Ostock", "Full");

        // ✅ Self 링크 생성
        Link selfLink = WebMvcLinkBuilder.linkTo(
                WebMvcLinkBuilder.methodOn(LicenseController.class)
                        .getLicense(licenseId))
                .withSelfRel(); // "self" 링크로 설정

        // ✅ 링크를 포함한 EntityModel 생성
        EntityModel<License> resource = EntityModel.of(license, selfLink);

        return ResponseEntity.ok(resource);
    }
}

📌 Step 3: API 응답에서 생성된 링크 확인

위의 컨트롤러를 실행하고, GET /api/licenses/123를 호출하면 다음과 같은 JSON 응답이 반환됩니다.

{
    "licenseId": "123",
    "description": "Software License",
    "productName": "Ostock",
    "licenseType": "Full",
    "_links": {
        "self": {
            "href": "http://localhost:8080/api/licenses/123"
        }
    }
}

"self" 링크: 현재 리소스를 다시 조회할 수 있는 경로 제공.
HATEOAS 적용: 클라이언트가 URL을 직접 구성할 필요 없이 _links에서 탐색 가능.

🚀 3. WebMvcLinkBuilder의 주요 메서드

메서드 설명 예제
linkTo 특정 컨트롤러의 기본 URL 생성 linkTo(LicenseController.class)
methodOn 특정 컨트롤러 메서드의 URL 생성 methodOn(LicenseController.class).getLicense("123")
withSelfRel Self 링크 추가 ("self") linkTo(...).withSelfRel()
withRel 특정 관계(Rel)를 가진 링크 추가 linkTo(...).withRel("update")
toUri() URI 객체 반환 linkTo(...).toUri()

🎯 4. 다양한 링크 추가하기

1) 여러 개의 링크 추가

@GetMapping("/{licenseId}")
public ResponseEntity<EntityModel<License>> getLicense(@PathVariable String licenseId) {

    License license = new License(licenseId, "Software License", "Ostock", "Full");

    // ✅ Self 링크
    Link selfLink = linkTo(methodOn(LicenseController.class).getLicense(licenseId))
                    .withSelfRel();

    // ✅ 업데이트 링크
    Link updateLink = linkTo(methodOn(LicenseController.class).updateLicense(licenseId, license))
                    .withRel("update");

    // ✅ 삭제 링크
    Link deleteLink = linkTo(methodOn(LicenseController.class).deleteLicense(licenseId))
                    .withRel("delete");

    // ✅ 전체 목록 조회 링크
    Link allLicensesLink = linkTo(methodOn(LicenseController.class).getAllLicenses())
                    .withRel("all-licenses");

    EntityModel<License> resource = EntityModel.of(license, selfLink, updateLink, deleteLink, allLicensesLink);

    return ResponseEntity.ok(resource);
}

self, update, delete, all-licenses 등 여러 링크를 추가.
✅ 클라이언트가 API 응답을 보고 바로 필요한 API 호출 가능.

2) API 응답 확인

{
    "licenseId": "123",
    "description": "Software License",
    "productName": "Ostock",
    "licenseType": "Full",
    "_links": {
        "self": { "href": "http://localhost:8080/api/licenses/123" },
        "update": { "href": "http://localhost:8080/api/licenses/123" },
        "delete": { "href": "http://localhost:8080/api/licenses/123" },
        "all-licenses": { "href": "http://localhost:8080/api/licenses" }
    }
}

✅ 클라이언트는 _links 내 링크를 사용해 API를 동적으로 탐색 가능.
self 링크로 현재 리소스 조회, update/delete 링크로 수정·삭제 수행.

📌 5. WebMvcLinkBuilder 사용의 장점

1) URL 하드코딩 방지

  • API 경로가 변경되더라도 자동으로 반영됨.
  • 개발자가 직접 URL을 관리할 필요 없음.

2) HATEOAS 지원

  • 클라이언트가 서버의 URI 구조를 몰라도 _links를 활용해 API 탐색 가능.

3) 유지보수성 향상

  • 엔드포인트가 변경되면 자동으로 링크가 업데이트되므로 코드 수정이 적음.

🎯 6. WebMvcLinkBuilder의 실제 활용

1) API 변경 시 자동 반영

// 기존 엔드포인트
@RequestMapping("/api/licenses")
public class LicenseController { }

// 엔드포인트 변경
@RequestMapping("/api/v2/licenses")
public class LicenseController { }

WebMvcLinkBuilder를 사용하면 API 경로가 변경되더라도 자동 반영됨!
✅ 클라이언트가 _links를 사용하여 API를 동적으로 탐색하면 API 변경 시 문제 발생 가능성 줄어듦.

🎉 7. 결론

WebMvcLinkBuilder는 Spring HATEOAS에서 REST API의 하이퍼미디어 링크를 생성하는 핵심 도구
URL을 직접 하드코딩하지 않고, 컨트롤러 메서드를 기반으로 자동 생성 가능
Self 링크뿐만 아니라, 업데이트·삭제·목록 조회 등의 링크를 함께 제공 가능
클라이언트가 _links를 활용해 API를 동적으로 탐색할 수 있어 REST API의 UX가 향상됨 🚀

 

📌 Summary
WebMvcLinkBuilder는 RESTful API에서 HATEOAS를 구현하는 데 필수적인 클래스이며,
URL 하드코딩 없이 자동으로 링크를 생성하여 유지보수성을 높이고 API의 확장성을 극대화하는 강력한 도구입니다. 🚀

'Spring Framework > Spring HATEOAS' 카테고리의 다른 글

HATEOAS(Hypermedia as the Engine of Application State)  (0) 2025.03.03
_links  (0) 2024.12.11
self 링크  (0) 2024.12.09
EntityModel  (0) 2024.12.09
RepresentationModel  (0) 2024.12.09