ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [19] Spring Web MVC : Spring HATEOAS
    Spring/Spring boot 2020. 6. 30. 08:36
    반응형

    [HATEOAS]

    Hypermedia As The Engine Of Application State(HATEOAS)는 application의 상태(state)를 관리하기 위한 기술입니다. 이 기술은 기존 REST API의 단점[각주:1]을 보완한 것으로, client는 특정 resource에서 이동할 수 있는 다른 resource에 대한 link를 server로부터 전달받아 사용합니다. (client가 접근할 수 있는 resource에 대한 link를 미리 알아야 하는 이유는 무엇?)

     

    Spring HATEOAS는 Spring framework에서 HATEOAS를 구현하기 위해 제공되는 library입니다.

     

    HATEOAS에 의해 생성되는 response data에는 사용 가능한 자원인지 여부에  따라 접근 가능한 API들이 links로 제공됩니다.

    {
      “accountId”:12345,
      “accountType”:”saving”,
      “balance”:350000”,
      “currency”:”KRW”
      “links”: [
           {
           “rel”: “self”
           “href”: “http://localhost:8080/accounts/1”
           },
           {
           “rel”: “withdraw”,
           “href”: “http://localhost:8080/accounts/1/withdraw”
           },
           {
           “rel”:”transfer”,
             “href”:”http://localhost:8080/accounts/1/transfer”
           }
      ]
    }

     

    HATEOAS에 대한 읽을거리: https://m.blog.naver.com/PostView.nhn?blogId=tmondev&logNo=220391644590&proxyReferer=https:%2F%2Fwww.google.com%2F

     

     

     


    [Spring HATEOAS]

    spring boot에서 HATEOAS를 사용하기 위해서는 다음과 같은 의존성을 추가해야 합니다.

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

    이 의존성을 추가하면 여러가지 자동설정이 진행되면서 ObjectMapper와 LinkDiscovers를 사용할 수 있도록 제공해 줍니다.

     

     

    ObjectMapper

    spring.jackson.*에서 제공하는 class로써, 전달하고자 하는 resource를 JSON으로 변환하는데 사용하는 interface입니다.

    ObjectMapper를 customizing 하기 원하는 경우는 application.properties file 아래에 spring.jackson.* 에 해당하는 키의 값을 변경하면 됩니다.

     

     

    LinkDiscovers

    xPath를 확장해서 만든 HATEOAS용 client용 API입니다.

     

     


    [Spring HATEOAS의 활용 예]

    ~/hello 로 get request를 넣었을 때 link 정보를 포함한 response를 되돌려 주는 service를 구현해보도록 합니다.

     

    1. reqeust에 대해 정상적으로 link 정보를 포함하여 response하는지 test합니다.

    import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
    import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
    
    @RunWith(SpringRunner.class)
    @WebMvcTest(SampleController.class)
    public class SampleControllerTest {
    
        @Before
        public void setUp() throws Exception {
        }
    
        @Autowired
        MockMvc mockMvc;
    
        @Test
        public void hello_test() throws Exception {
            mockMvc.perform(get("/hello"))
                    .andDo(print())
                    .andExpect(status().isOk())
                    .andExpect(jsonPath("$._links.self").exists());   //	①
    
        }
    
        @After
        public void tearDown() throws Exception {
        }
    }

    ① HATEOAS에 의해 추가되는 response 정보는 links가 포함됩니다. self에 해당하는 link 정보가 있는지 확인합니다.

     

     

    2. test를 통과하기 위한 controller를 작성합니다.

    @RestController
    public class SampleController {
    
        @GetMapping("/hello")
        public Resource<Hello> hello() {
            Hello hello = new Hello();
            hello.setPrefix("Hey, ");
            hello.setName("Dave");
    
            Resource<Hello> helloResource = new Resource<>(hello);  //	①
            helloResource.add(linkTo(methodOn(SampleController.class)	//	②
                    .hello()).withSelfRel());
    
            return helloResource;
        }
    }

    ① Resource<T> type의 객체는 우리가 제공하는 resource에 link정보를 더한 것입니다.

    ② SampleController class의 hello() method에 대한 link를 따서 self라는 relation으로 추가합니다.

    (주의) 위 code는 spring boot 2.0.3에 맞춰 작성된 것입니다. 2.2.7은 Resource <T> 대신 다른 type을 사용해야 하는 것으로 보입니다.

     

     

    3. controller에서 사용할 Hello class를 작성합니다.

    public class Hello {
    
        private String prefix;
    
        private String name;
    
        public String getPrefix() {
            return prefix;
        }
    
        public void setPrefix(String prefix) {
            this.prefix = prefix;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return prefix + "" + name;
        }
    }

     

     

    test code를 실행해보면 reponse data에 다음과 같이 links 정보가 포함된 것을 확인해볼 수 있습니다.

    1. 1. End Point의 URI가 제공된 뒤에 변경하기가 어렵습니다. 제공받은 모든 client가 수정된 URI로 변경해야 합니다.

      2. 작업 수행이 가능한지에 대해 판단하는 기능을 client가 가지고 있어야 합니다. [본문으로]

    'Spring > Spring boot' 카테고리의 다른 글

    [21] Spring Data : In-memory Database  (0) 2020.07.07
    [20] Spring Web MVC : CORS  (0) 2020.07.04
    [18] Spring Web MVC : ExceptionHandler  (0) 2020.06.28
    [17] Spring Web MVC : HtmlUnit  (0) 2020.06.26
    [16] Spring Web MVC : Template Engine  (0) 2020.06.24

    댓글

Designed by Tistory.