내일배움캠프 Spring 55일차(수) TIL - SpringDataJpa(HATEOAS)

Skadi·2024년 3월 13일
0

HATEOAS

HATEOAS(Hypermedia As The Engine of Application State)는 RESTful API 설계 원칙 중 하나로, 클라이언트가 서버와 상호작용하는 방식에 있어서 하이퍼미디어(주로 하이퍼링크)를 통해 애플리케이션의 상태를 관리하고, 다음 가능한 모든 작업을 동적으로 안내받을 수 있도록 합니다. 즉, API 응답에 다음 가능한 액션에 대한 링크를 포함시켜, 클라이언트가 해당 링크를 통해 필요한 작업을 수행할 수 있게 하는 것입니다. 이를 통해 API의 Discoverability(발견 가능성)을 높이고, 클라이언트와 서버 간의 결합도를 낮출 수 있습니다.

얼만큼? 클라이언트 화면이 필요 없을 만큼!! (서버리스가 아닌 클라이언트리스)

HATEOAS 기본 적용 예시

게시글 조회 API를 호출했을때

{
  "data": {
    "id": 1000,
    "name": "게시글 1",
    "content": "HAL JSON을 이용한 예시 JSON",
    "self": "http://localhost:8080/api/post/1000", // 호출한 api 주소
    "profile": "http://localhost:8080/docs#query-article", // 호출한 api 문서
    "next": "http://localhost:8080/api/post/1001", // 다음 post를 조회 api 주소
    "comment": "http://localhost:8080/api/post/comment", // post의 댓글 달기 api 주소
    "save": "http://localhost:8080/api/feed/post/1000", // post을 내 피드로 저장 api 주소
  },
}

HATEOAS를 SpringDataJPA 페이징에 적용

  1. HATEOAS 의존성 추가 (spring-boot-starter-hateoas)
// 9. SpringBoot HATEOAS 의존성 추가
implementation 'org.springframework.boot:spring-boot-starter-hateoas'
  1. 핸들러 매개변수로 PagedResourcesAssembler 넣고 PagedModel 로 응답
@RestController
public class ChannelController {

  @Autowired
  ChannelRepository channelRepository;

  @GetMapping("/channels")
  public PagedModel<User> getUsers(Pageable pageable, PagedResourcesAssembler<User> assembler) {
    var all = channelRepository.findAll(pageable);
    return assembler.toModel(all);
  }

}
  1. 적용 전 응답 (기본 Pageable)
{  
   "content":[  
...
      {  
         "id":140,
         "title":"jpa"
      }
   ],
   "pageable":{  
      "sort":{  
         "sorted":true,
         "unsorted":false
      },
      "offset":20,
      "pageSize":10,
      "pageNumber":2,
      "unpaged":false,
      "paged":true
   },
   "totalElements":200,
   "totalPages":20,
   "last":false,
   "size":10,
   "number":2,
   "first":false,
   "numberOfElements":10,
   "sort":{  
      "sorted":true,
      "unsorted":false
   }
}
  1. 적용 후 응답 (PageModel (PagedResource))
{  
   "_embedded":{  
      "channelList":[  
         {  
            "id":140,
            "title":"jpa"
         },
...
         {  
            "id":109,
            "title":"jpa"
         }
      ]
   },
   "_links":{  
      "first":{  
         "href":"http://localhost/channels?page=0&size=10&sort=created,desc&sort=title,asc"
      },
      "prev":{  
         "href":"http://localhost/channels?page=1&size=10&sort=created,desc&sort=title,asc"
      },
      "self":{  
         "href":"http://localhost/channels?page=2&size=10&sort=created,desc&sort=title,asc"
      },
      "next":{  
         "href":"http://localhost/channels?page=3&size=10&sort=created,desc&sort=title,asc"
      },
      "last":{  
         "href":"http://localhost/channels?page=19&size=10&sort=created,desc&sort=title,asc"
      }
   },
   "page":{  
      "size":10,
      "totalElements":200,
      "totalPages":20,
      "number":2
   }
}

HATEOAS 적용의 장점

  1. Discoverability 증가: 클라이언트는 응답으로 받은 링크를 통해 어떤 작업을 할 수 있는지를 알 수 있으므로, API 사용자가 다른 문서를 참조하지 않고도 API를 탐색할 수 있습니다.
  2. 유연성 및 확장성 향상: 서버 측에서 URI가 변경되더라도 클라이언트는 응답에 포함된 링크 정보를 이용하기 때문에, 변경에 대한 영향을 덜 받습니다. 이는 API의 유지 보수성과 확장성을 향상시킵니다.
  3. 클라이언트-서버 간의 결합도 감소: 클라이언트는 서버로부터 제공받은 링크 정보만을 사용하기 때문에, 내부 구현에 대한 의존도가 낮아집니다.

HATEOAS 적용 예시 보완

제시해주신 HATEOAS 적용 예시는 클라이언트가 게시글 조회 API를 호출했을 때, 다음 작업을 위한 링크들을 포함하여 응답하는 것을 보여줍니다. 이는 클라이언트가 다음 가능한 작업을 API 문서 없이도 직관적으로 알 수 있게 해줍니다. 예시에 나온 self, profile, next, comment, save와 같은 링크들은 사용자에게 다음 가능한 작업을 안내합니다.

Spring Data JPA와 HATEOAS

Spring Data JPA 페이징 처리와 함께 HATEOAS를 적용하면, 페이징 처리된 데이터와 함께 현재 페이지, 이전/다음 페이지, 첫 페이지, 마지막 페이지 등의 링크를 제공하여 클라이언트가 API를 더 효율적으로 사용할 수 있게 합니다. PagedResourcesAssembler 객체를 사용하여 페이지 정보와 함께 _links 정보를 포함한 PagedModel을 생성하고, 이를 응답으로 반환합니다.

추가 사항

  • 의존성 추가: Spring HATEOAS를 사용하기 위해서는 spring-boot-starter-hateoas 의존성을 프로젝트에 추가해야 합니다.
  • Controller 수정: PagedResourcesAssembler를 사용하여 페이징 정보와 함께 링크 정보를 포함한 응답을 생성합니다.
  • 응답 구조 변화: HATEOAS 적용 후 응답 구조에는 _links 필드가 추가되어, 클라이언트는 해당 링크를 통해 추가적인 작업을 수행할 수 있습니다.

HATEOAS를 적용함으로써 RESTful API의 자기서술성(self-descriptive)과 연결성(linkability)을 향상시키고, API를

보다 유연하고 직관적으로 사용할 수 있게 됩니다.

0개의 댓글