Spring/스프링 기본

Glory of Rest 란 뭘까? + HATEOS 적용기

공대키메라 2022. 2. 16. 18:12

최근에 필자가 HATEOS 의 기능에 대해 어쩌다가 알게 되었는데 이와 관련된 설명들을 찾아보았다.

HATEOS는 무엇이며 HATEOS는 왜 쓰는 것일까? 그전에 알아야 하는 정보에 대해서 설명하고자 한다. 

 

https://martinfowler.com/articles/richardsonMaturityModel.html

 

한국어로 내가 훔쳐(?)서 적는 것보다 영어로 직접 읽기를 바라는 분들은 위의 출처 사이트를 참조하면 된다. 

1. Glory of Rest

우선  Glory of Rest 가 무엇인지 알아야 할 것 같다. 

 

REST를 위한 영광의 단계라는데... REST를 잘 활용하기 위한 단계라고 보면 될 것 같다.

 

REST 는 우선 많은 사람들이 알고 있겟지만 Representational State Transfer의 약자로 효율적, 안정적이며 확장가능한 분산시스템을 가져올 수 있는소프트웨어 아키텍처 디자인 제약의 모음을 나타냅니다. 그리고 그 제약들을 준수했을 때 그 시스템은 RESTful하다고 일컬어집니다.

출처 : https://developer.mozilla.org/ko/docs/Glossary/REST

 

이 Glory of Rest는 Richardson 이  소개한 것으로 Richardson maturity model의 내용으로 소개되고 있다. 

 

출처 : https://martinfowler.com/articles/richardsonMaturityModel.html

 

다음 글들은 마틴 파울러 닷 컴에서 찾을 수 있는 이야기로, 유명한 그가 올린거 같다!

 

우선 글을 한번 읽어보겠다.

 

steps toward the glory of REST

A model (developed by Leonard Richardson) that breaks down the principal elements of a REST approach into three steps. These introduce resources, http verbs, and hypermedia controls.

glory of REST 를 위한 단계

REST의 원칙적 성분들을 무너뜨리는, 레오나드 리차드슨에 의해 개발된 이 모델은 세 단계로 접근한다. 
이것들은 리소스, http 동사, 하이퍼미디어 제어를 소개한다. 

 

그리고 CONTENTS에는 level 0 부터 level 3까지 소개를 하고 있다. 

 

출처 : https://martinfowler.com/articles/richardsonMaturityModel.html

 

https://jinson.tistory.com/190

 

이것을 한글로 번역하면서 공부를 하려 했는데 말이다.. 생각보다 스압으로 고생을 했다. 

 

그래서 찾다보니 이미 한글화해놓으신 분이 계셔서 긁을 읽고 사이트를 첨부했다. 

LEVEL 0

기존의 리소스를 웹 서비스 형태로 제공해서 단순히 URI만 매핑한 형태.

어떠한 요청을 할 것인이 URI에 명시가 되어있음

 

ex : http://server/getPosts, http://server/getPosts 등등의 방식!

LEVEL 1

외부에 공개하고자 하는 리소스에 대해서 의미있고 적절한 URI로 표현하기 시작.

일정한 패턴을 가지고 작성. HTTP의 메소드로 서비스를 구분해서 사용하지는 않음.

사용자 요청을 단순히 get과 post 형식으로 처리하고 반환값을 200 혹은 에러로만 단순하게 처리.

 

ex: http://server/account,. http://server/accounts/10

LEVEL 2

LEVEL 1 에 HTTP Methods(GET, POST, PUT, DELETE) 를 추가 

LEVEL 3

Level 2 에 HATEOS 기능을 추가.

 

다음 작업으로 어떤 것을 할 수 있는지 또 그 작업을 하기 위해서 다뤄지는 URI에는 어떤 것이 있는지 알려주는 기능이 포함되어 있음.

 

클라이언트측의 서버가 제공하는 서비스를 일일이 찾는 수고를 하지 않아도 된다. endpoint만 가지고도 다음 uri를 알 수 있음.

 

그러면 HATEOAS는 어떻게 사용하는 것인지 알아보자

HATEOAS 적용

 

이 친구(오늘의 친구는 내일의 적...)를 사용하기 위해 간단하게 spring boot 를 구성할것이다. 

 

 

그리고 파일은 간단하게 다음과 같이 구성했다. 

 

Member.java

package hateoas.hateoastest;

import com.fasterxml.jackson.annotation.JsonFilter;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
//@JsonFilter("MemberFilter")
public class Member {

    private String name;
    private String password;

    public Member(String name, String password) {
        this.name = name;
        this.password = password;
    }
}

TestClassForHT.java

@RestController
public class testClassForHT {
    Map<Long, Member> memberMap = new HashMap<>();

    @PostConstruct
    public void init() {
        System.out.println("testClassForHT.settingDummy");
        for(int i = 0; i < 10; i++){
            memberMap.put(Long.valueOf(i), new Member("member" + i, "123456"));
        }
    }

    @GetMapping("/users/{id}")
    public EntityModel<Member> testingMember(@PathVariable Long id){

        Member member = memberMap.get(id);

        EntityModel<Member> model = EntityModel.of(member);
        WebMvcLinkBuilder linkTo = WebMvcLinkBuilder.linkTo(WebMvcLinkBuilder.methodOn(this.getClass()).retrieveAllMembers());
        model.add(linkTo.withRel("all-members"));

        return model;
    }
    
    ...
    
   @GetMapping("/users")
   public MappingJacksonValue retrieveAllMembers(){
  	 	List<Member> users = new LinkedList<>();
        for(Long id : memberMap.keySet()){
            Member member = memberMap.get(id);
            users.add(member);
        }
        SimpleBeanPropertyFilter filter = SimpleBeanPropertyFilter
                .filterOutAllExcept("password");

        FilterProvider filters = new SimpleFilterProvider().addFilter("MemberFilter", filter);

        MappingJacksonValue mapping = new MappingJacksonValue(users);
        mapping.setFilters(filters);
        return mapping;
   }
 }

 

Postman 에서 실행해보면... 

 

다음과 같이 _link가 추가된것을 확인할 수 있다. 

 

근데 오히려 이렇게 해서 일만 더 늘어나는거 같고 도대체 장점이 뭔지 몰라서 한번 찾아보았다.

HATEOAS의 장점

  1. 요청 URI가 변경되더라도 클라이언트에서 동적으로 생성된 URI를 사용함으로써, 클라이언트가 URI 수정에 따른 코드를 변경하지 않아도 되는 편리함을 제공합니다.
  2. URI 정보를 통해 들어오는 요청을 예측할 수 있게 됩니다.
  3. Resource가 포함된 URI를 보여주기 때문에, Resource에 대한 신뢰를 얻을 수 있습니다.
  4. 클라이언트가 제공되는 API의 변화에 일일이 대응하지 않아도 되는 편리함을 얻을 수 있습니다.

출처 : https://kchanguk.tistory.com/117 

 

단점은... 아마 코드량이 늘어나서 개발자가 화가(?) 난다는 것 아닐까...?