IT/development

[Spring] spring REST API 공부(feat. @RestController)

알 수 없는 사용자 2022. 11. 22. 07:02
반응형

목차

     

    REST란? 😎

    REST란 "Representational State Transfer"의 약자이고 직역하면 대표상태 전송이다.

    하나의 URI는 고유한 리소스를 대표하도록 설계된다는 개념인데 솔직히 아직 정확히 이해하지는 못했다.

    웹의 모든 리소스에 고유한 URI로 의미부여 한 뒤 HTTP Method를 통해 상태를 주고 받으며 통신하는 방식이라고 이해 했다.

    그리고 서버에서 클라이언트로 반환하는 값이 순수한 데이터라는 점

    클라이언트가 URI만 봐도 이게 무슨 작업을 의미하는지 알 수 있도록 설계해야 한다.

    ex)localhost:8080/user가 URI이고 POST으로 서버에 전송한다고 하면 사용자 등록이라고 유추할 수 있다.

    REST 방식에서는 HTTP Method가 CRUD를 의미한다. 그래서 위 URI에서 굳이 /user 뒤에 insert 이런 주소를 더 붙일 필요가 없다.

    C(create): POST

    R(Read): GET

    U(Update): Put

    D(Delete): Delete

    또 백엔드 프론트엔드가 구분된다.

    즉 REST API 개발자는 데이터 형식과 규칙만 잘 정해서 약속된 데이터만 클라이언트로 반환해주면 된다.


    이제 스프링에서 REST API 개발하는 것 관련해서 정리한다. 시간 상 너무 깊게 정리는 못한다.

    공부할 게 너무 많다ㅠㅠ

     

    @RestController 😋

    간단히 정리한다.

    @Controller와 @ResponseBody를 합친 어노테이션을 의미한다.

    즉 @RestController 어노테이션을 사용하면 순수한 데이터만 클라이언트에게 전송한다.

    REST 방식에서 클라이언트는 HTTP BODY에 데이터를 담아서(주로 JSON 포맷) 서버로 보내고

    서버에서는 이를 JAVA객체로 변환하기 위해서(내부적으로 HttpMessageConverter가 처리) 사용하는 어노테이션이 @RequestBody임(클라이언트에서 JSON형식으로 보내면 서버에서는 반드시 이렇게 받아야 함, 아니면 데이터 바인딩이 안됨)

    삽질을 좀 했던 이유가 컨트롤러에서 @ModelAttribute MemberVO memberVO로 받고 클라이언트에서는 JSON형식으로 보냈더니 parameter값이 null로 세팅이 되었었다.

    더 찾아보니 @ModelAttribute를 통해 HTTP BODY값을 받으려면 Content-Type을 application/json이 아닌 multipart/form-data형태로 전송해야만 한다고 한다.

     

    클라이언트에서 JSON으로 보내는 건 반드시 @RequestBody로 받아야 된다.(서버와 클라이언트 사이 형식을 맞춰줘야 한다.)

    그리고 보낼 때도 @ResponseBody로 보내야 된다.

    서버에서 비지니스 로직 수행 후 데이터를 반환할 때 역시 HTTP BODY 형식에 맞춰서 반환해줘야 하는데

    이 때 사용되는 어노테이션이 @ResponseBody이다.

    즉, @RestController가 붙은 컨트롤러는 @ResponseBody형식으로 데이터를 반환한다.


     

    스프링에서 parameter값 바인딩 방법 😎

    @RequestParam 

    서버에서 parameter를 받을 때 객체로 받는게 아니라 정말 단일의 parameter값만 받을 때 사용됨, 또한 필수 parameter값도 이 방법으로 많이 받는다.(@RequestParam 생략도 가능함)

    서버와 클라이언트의 parameter 1:1매핑

    ex) localhost:8080/user?id=test

    위처럼 클라이언트에서 Get방식으로 id를 서버로 넘길 때 서버에서는 아래처럼 받으면 된다.

    아래는 localhost:8080/test/requestParam?id=test로 호출하면 ResponseEntity로 status 200과 parameter값으로 받은 id를 반환하는 코드이다.

     

    아래는 브라우저에서 테스트 한 결과이다. 쿼리스트링으로 id를 lsy로 서버로 던졌고 예상대로 상태코드는 200이 반환되었으며 Response를 보면 requestParam : id가 담겨져 있다.

    @RestContrller는 반환값을 HTTP BODY로 반환하도록 설계되어 있다.

    이렇게 그냥 단건의 parameter값을 주고 받을 때는 @RequestParam을 사용하면 되는데 여러건을 주고 받을 때는 아래처럼 @RequestParam을 여러번 작성해야 되는 불편함이 발생한다.

    이렇게 여러건의 parameter값을 받을 때는 @RequestParam을 작성하는 건 매우 비효율적이다.

     

    @ModelAttribute

    위처럼 여러개의 parameter값을 받을 때 사용되며 주로 데이터를 객체로 받을 때 사용한다.(dto, vo 등)

    dto나 vo를 아래처럼 생성해 놓고 이에 맞춰서 클라이언트에서 받을 때 사용됨

    데이터 받는 객체에 Setter가 반드시 설정되어 있어야 함

     

    아래는 localhost:8080/model?id=id&name=name으로 호출하면 MainVO을 반환하는 코드이다.

     

    아래는 브라우저에서 테스트한 결과이다.

    쿼리스트링으로 id와 name을 서버로 던졌고 MainVO와 매핑되어 데이터가 잘 반환되었다.

     

    만일 서버의 VO에 없는 값을 추가로 던지면 어떻게 될까? 🙄

    VO에는 현재 id와 name만 받을 수 있도록 되어 있다.

    VO에 없는 email을 추가해서 전송해봤다. 아래처럼 email값은 반환되지 않는다.

     

    @RequestBody

    클라이언트에서 서버로 전송하는 데이터 형식이 form-data가 아니라 HTTP BODY에 JSON형식으로 보내는 방식이라면 반드시 서버에서도 @RequestBody로 받아야 제대로 객체에 바인딩이 된다.

    아래코드는 localhost:8080/test/json으로 post방식으로 호출(JSON형식)하면 데이터를 받아서 @RestponseBody형식으로 반환하는 코드이다.

    JSON 테스트 하기 위해서 postman으로 내 로컬호스트로 전송을 해서 아래와 같은 결과가 나왔다.

    정상적으로 값이 반환되었다.

    클라이언트에서 POST방식으로 JSON형식으로 데이터를 HTTPBODY에 담아서 전송하는 이 경우에 

    서버에서 @RequestBody가 아니라 @ModelAttribute로 받게 되면 어떻게 될까?

     

    postman에서 테스트를 해보면 JSON형식으로 보낸 id와name이 서버에서 바인딩이 제대로 안되어 null값이 반환되었다.

     

    서버에서 @ModelAttribute로 받는 경우는 아래처럼 클라이언트의 데이터 전송형식을 form-data로 변경해야 바인딩이 제대로 된다.

     

    @PathVariable

    url의 일부를 parameter값으로 받을 때 사용됨(주로 idx와 같이 변수처럼 활용되는 경우 사용됨)

    localhost:9090/user/{idx}

    이런식으로 클라이언트에서 서버로 전송하면 서버에서는 해당 idx를 변수처럼 활용할 수 있다.

    @PathVariable("idx") String idx 이렇게 하고 @RequestMapping("/{idx}") 이런식으로 받아서 추출할 수 있다.

    아래코드는 url의 idx를 parameter값으로 던져서 사용자 정보를 가져온 뒤 반환하는 예제코드이다.

    localhost:8080/user/{idx}에서 idx를 parameter값으로 추출해서 MainService의 selectMemberByIdx에 전달

     

    브라우저에서 테스트를 해보면 아래처럼 결과가 반환된다.

    {idx}값으로 9999를 전달했고 9999에 해당되는 결과가 반환되었다.

     

    개인적으로 공부한 내용을 작성하는거라 틀린 부분이 있을 수 있습니다.

    틀린 내용이 있을 경우 댓글로 피드백 부탁 드립니다. 😅

    반응형