읽은 책 정리/코드로 배우는 스프링 웹 프로젝트

[Spring] 16 REST 방식으로 전환

포포015 2020. 12. 23. 11:28

모바일 시대가 되면서 WEB분야의 가장 큰 변화는 서버 역할의 변화라고 할수 있다.

과거에는 서버의 데이터를 소비하는 주체가 '브라우저'라는 특정한 애플리케이션으로 제한적이었다면,

모바일의 시대가 되면서 앱이나 웹은 서버에서 제공하는 데이터를 소비하게 된다.

과거의 서버는 브라우저라는 하나의 대상만을 상대로 데이터를 제공했기때문에,

아예 브라우저가 소화가능한 모든 데이터를 HTML이라는 형태로 전달하고,

브라우저는 이를 화면에 보여주는 역할을 해왔다.   

 

스마트폰에서는 앱(APP)이라 불리는 고유한 애플리케이션을 이용해서, 데이터를 소비하게 되고

보이는 화면 역시 자신만의 방식으로 서비스 하게된다.

앱에서 서버에 기대하는 것은 완성된 HTML이 아니라 그저 자신에게 필요한 순수한 데이터만을 요구하게 되었다.

브라우저와 앱은 서버에서 전달하는 데이터를 이용해서  앱 혹은 브라우저 내부에서 별도의 방식을 통해서,

이를 소비하는 형태로 전환하고 있다.

 

이러한 변화속에서 웹의 URI 의미도 조금 다르게 변화했다.

과거에는 제작된 웹페이지들의 경우 페이지를 이동하더라도 브라우저의 주소는 변화하지 않는 방식을 선호반면 최근의 웹페이지들은 대부분 페이지를 이동하면 브라우저 내의 주소 역시 같이 이동하는 방식을 사용.

 

흔히 URL과 URI를 같은의미로 사용하는경우가 많다. 엄밀하게 URL은 URI의 하위개념이기때문에 혼용해서 사용가능

 

REST는 'Representational State Transfer'의 약어로 하나의 URI은 하나의 고유한 리소스(Resource)를 대표하도록

설계된다는 개념에 전송방식을 결합해서 원하는 작업을 지정한다.

 

예를 들어 '/boards/123'은 게시물중에서 123번이라는 고유한 의미를 가지도록 설계하고,

이에대한 처리는 GET,POST 방식과 같이 추가적인 정보를 통해서 결정한다

 

 

@Controller 어노테이션과

@RestController의 차이는 반환타입이 차이만 있음.

Controller는 문자열을 반환하는경우 JSP파일의 이름으로 처리하지만

RestController는 return 자체에 순수한데이터 넣어 보낸다.

 

객체의 반환하는 작업은 JSON 이나 XML을 이용.(전달된 객체를 생산하기위해 VO클래스 작성)

하고 Controller에서는 VO클래스를 리턴하는 메서드를 설계 

1
2
3
4
5
    @GetMapping(value = "/getSample", produces= {MediaType.APPLICATION_JSON_UTF8_VALUE, MediaType.APPLICATION_XML_VALUE}) //XML과 JSON방식의 데이터를 생성함.
    public SampleVO getSample() {
 
        return new SampleVO(112,"스타","로드");
    }
cs

getSample는 XML과 JSON방식의 데이터를 생성할수 있도록 작성 되었다.

브라우저에서 일반적으로 /getSample을 호출하면 XML 데이터로 출력/ URI뒤에 .json을 호출하면 JSON데이터타입 호출

 

아래처럼 produces속성은 반드시 지정해야하는것은 아님 (생략가능)

1
2
3
4
5
    @GetMapping(value = "/getSample2")
    public SampleVO getSample2() {
 
        return new SampleVO(113,"로켓","라쿤");
    }
cs

 

*컬렉션타입의 객체반환

경우에 따라서는 여러 데이터를 한번에 전송하기 위해서 배열이나 리스트,맵타입의 객체들을 전송하는경우 발생.

 

맵의 경우'키'와 '값'을 가지는 하나의 객체로 간주됨

Map을 이용하는 경우 '키(key)'에 속하는 데이터는 XML로 변환되는 경우에 태그의 이름이 되기때문에 문자열지정

1
2
3
4
5
6
7
8
@GetMapping(value = "/getMap")
    public Map<String, SampleVO> getMap(){
            
            Map<String, SampleVO> map = new HashMap<>();
            map.put("first"new SampleVO(111"그루트""주니어"));
        
            return map;
        }
cs

 

16.2.4 ResponseEntity 타입

Rest 방식으로 호출하는 경우는 화면 자체가 아니라, 데이터 자체를 전송하는 방식으로 처리되기 때문에,

데이터를 요청한쪽에서는 정상적인 데이터인지 비정상적인 데이터인지를 구분할수 있는 방법을 제공해야함.

ResponseEntity는 데이터와 함께 HTTP 헤더의 상태 메시지등을 같이 전달하는 용도로 사용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@GetMapping(value = "/check", params= {"height""weight"})
    public ResponseEntity<SampleVO> check(Double height, Double weight){
        
        SampleVO vo = new SampleVO(0"" + height, ""+ weight);
        
        ResponseEntity<SampleVO> result = null;
        
        if(height < 150) {
            result = ResponseEntity.status(HttpStatus.BAD_GATEWAY).body(vo);
        }else {
            result = ResponseEntity.status(HttpStatus.OK).body(vo);
        }
        
        return result; 
        
    }
cs

check()는 반드시 'height'와 'weight'를 파라미터로 전달받는다.

만약 'height'값이 150보다 작다면 502(bad gateway)상태 코드와 데이터를 전송하고,

그렇지 않다면 200(ok)코드와 데이터 전송.

 

1
http://localhost:8080/sample/check.json?height=140&weight=60
cs

위와 같이 JSON 타입의 데이터를 요구하고 , height 값을 150보다 작게하는 경우 502 메시지와 데이터 전달.

 

16.3 @RestController에서 파라미터

@RestController는 기존의 @Controller에서 사용하던 일반적인 타입이나 사용자가 정의한 타입(클래스)를 사용

추가로 몇가지 어노테이션을 이용하는경우가 있다.

- @PathVariable : 일반 컨트롤러에서도 사용가능하지만 REST방식에서 자주사용.

                      URL 경로의 일부를 파라미터로 사용할때 이용

- @RequestBody : JSON 데이터를 원하는 타입의 객체로 변환해야 하는경우에 주로 사용

 

16.3.1 @PathVariable

Rest방식에서는 URL내에 최대한 많은 정보를 담으려고 한다.

예전에는 '?' 뒤에 추가되는 쿼리스트링(query string)이라는 형태로 파라미터를 이용해서 전달되던

데이터들이 REST 방식에서는 경로의 일부로 차용되는경우가 많다.

스프링 MVC에서는 @PathVariable 어노테이션을 이용해서 URL 상에 경로의 일부를 파라미터로 사용

1
2
http://localhost:8080/sample/{sno}
http://localhost:8080/sample/{sno}/page/{pno}
cs

위에 URL에서 '{}'로 처리된 부분은 컨트롤러의 메서드에서 변수로 처리가 가능.

@PathVariable은 '{}'의 이름을 처리할때 사용

 

 

16.3.2 @RequestBody 

@RequestBody는 전달된요청(request)의 내용(body)을 이용해서 해당 파라미터의 타입으로 변환을 요구

대부분의 경우에는 JSON 데이터를 서버에 보내서 원하는 타입의 객체로 변환하는 용도로 사용되지만,

경우에 따라서는 원하는 포맷의 데이터를 보내고,이를 해석해서 원하는 타입으로 사용