[Spring] REST API
REST
REST(Representational State Transfer)란 자원(URI)과 행위(Http Method)를 기반으로 데이터를 주고 받는 방법을 말한다. REST 원리를 따르는 시스템은 RESTful이란 용어로 지칭된다.
CRUD Operation
행위(Http Method) | 설명 |
---|---|
POST | Create |
GET | Read |
PUT | Update |
DELETE | Delete |
HEAD | Header 정보조회 |
장점
- HTTP 프로토콜 인프라를 그대로 사용 가능
- HTTP 프로토콜이 사용가능한 모든 플랫폼에서 사용이 가능 - 다양한 브라우저와 모바일 디바이스에서 통신
단점
- 명확한 표준이 존재하지 않는다.
- 사용할 수 있는 메서드가 4가지 밖에 없다.
- 구현 브라우저는 PUT, DELETE를 사용할 수 없다.
Spring REST API
@RestController
JSP와 같은 view를 반환하는 것이 아니고 JSON, XML같은 데이터를 브라우저로 전송하는 컨트롤러
@RestController
@RequestMapping("/test/*")
public Class TestController{
// 문자열 전달
@RequestMapping("/hello")
public String hello(){
return "hello REST!";
}
// VO객체를 JSON으로 전달
@RequestMappring("/member")
public MemberVO member(){
MemberVO vo = new MemberVO();
vo.setID("SYKIM");
vo.setPwd("1234");
return vo;
}
...
}
VO 객체는 물론 Collection(Map, List 등) 객체도 JSON으로 전달된다.
@PathVariable
브라우저에서 요청 URI로 전달된 매개변수를 가져올 수 있다.
@RequestMapping(value = "/notice/{num}", method = RequestMethod.GET)
public int notice(@PathVariable("num") int num) throws Exception{
return num;
}
브라우저에서 요청 시, {num}
부분의 값이 @PathVariable로 지정된다.
@RequestBody
REST는 Ajax와 연동해서 자주 사용되는데, 브라우저에서 JSON 데이터를 컨트롤러로 전송 시, @RequestBody를 사용하면 컨트롤러에서 전송받은 JSON을 객체로 변환하는 기능을 구현한다.
@RequestMapping(value= "/info", method= RequestMethod.POST )
public void modify(@RequestBody MemberVO vo){
// JSON으로 전송된 데이터를 MemberVO 객체의 속성에 자동 설정
logger.info(vo.toString());
}
$(function(){
$('#checkJson').click(function(){
var member = { id: 'hong', name: '홍길동', pwd: '1234'};
$.ajax({
type: 'post',
url: '${contextPath}/test/info',
contentType: 'application/json',
data: JSON.stringfy(member), // 회원정보 객체를 JSON 문자열로 변환
...
});
});
});
@ResponseBody
RestController로 지정하지 않았어도 ResponseBody가 적용된 메서드는 JSP가 아닌 JSON으로 결과를 전송한다.
@Controller
public class Controller{
@RequestMapping("/res1");
@ResponseBody
public Map<String, Object> res1(){
Map<String, Object> map = new HashMap<String, Object>();
map.put("id","hong");
map.put("name","홍길동");
// Map 데이터를 브라우저로 전송
return map;
}
}
@ResponseEntity
예외에 대한 세밀한 제어가 필요한 경우 ResponseEntity 클래스를 사용하여 HTTP 상태코드를 설정하여 전송하도록 한다.
...
public ResponseEntity<List<MemberVO>> listMembers(){
List<MemberVO> list = new ArrayList<MemberVO>();
...
return new ResponseEntity(list, HttpStatus.INTERNAL_SERVER_ERROR); // 오류코드 500 응답
}
- ResponseEntity에서 설정할 수 있는 HTTP 상태코드 (일부)
코드 | 상수 |
---|---|
200 | OK |
201 | CREATED |
400 | BAD_REQUEST |
403 | FORBIDDEN |
404 | NOT_FOUND |
500 | INTERAL_SERVER_ERROR |
HttpHeaders 클래스를 이용하여 ResponseEntity 전송
...
public ResponseEntity res3(){
HttpHeaders responseHeaders = new HttpHeaders();
// 전송할 데이터의 종류와 인코딩 설정
responseHeaders.add("Content-Type","text/html;charset=utf-8");
String message = "<script>";
message += "alert('새 회원을 등록합니다.')";
message += "location.href='/...'; ";
message += "</script>";
// ResponseEntity를 이용해 HTML 형식으로 전송
return new ResponseEntity(message, responseHeaders, HttpStatus.CREATED);
}
위 메서드가 매핑된 주소로 접속하면, message
에 입력한 자바스크립트 경고메시지가 표시된다.
ResponseEntity를 사용하면, JSON 뿐만 아니라 HTML 또는 자바스크립트를 브라우저로 전송할 수 있어 결과메시지 또는 오류메시지를 전송할 때 편리하다.
REST방식으로 URI 표현하기
REST방식에서는 조회 뿐만 아니라 추가, 수정, 삭제 (CRUD) 기능을 수행할 때 포스팅 상위에 작성한 것처럼 HTTP 메서드를 이용하여 처리해야한다.
REST 요청 URI의 예
/작업명/기본키 + 메서드 + 데이터
- 작업명 : 요청 작업의 종류
/boards
- 기본키 : 작업 대상의 기본 키
/133
- 메서드 : 수행 기능
- 데이터 : 기능 수행 시 필요한 JSON 데이터
메서드 | URI | 설명 |
---|---|---|
POST | /boards+데이터 | 새 글 등록 |
GET | /boards/133 | 133번 글 조회 |
PUT | /boards/133+데이터 | 133번 글 수정 |
DELETE | /boards/133 | 133번 글 삭제 |
예제 코드
@RestController
@RequestMapping("/boards")
public class BoardController{
...
// articleNO에 해당하는 글 조회 - GET
@RequestMapping(value = "/{articleNO}", method = RequestMethod.GET)
public ResponseEntity<ArticleVO> findArticle(@PathVarialbe("articleNO") Integer articleNO){
...
return new ResponseEntity<ArticleVO>(vo, HttpStatus.OK);
}
// JSON으로 전달된 객체를 새 글로 추가 - POST
@RequestMapping(value = "", method = RequestMethod.POST)
public ResponseEntity<String> addArticle(@RequestBody ArticleVO articleVO){
ResponseEntity<String> resEntity = null;
try{
resEntity = new ResponseEntity("ADD_SUCCEDED",HttpStatus.OK);
}catch(Exception e){
resEntity = new ResponseEntity(e.getMessage(),HttpStatus.BAD_REQUEST);
}
return resEntity;
}
// articleNo에 해당하는 글을 JSON으로 전달된 객체로 수정 - PUT
@RequestMapping(value = "/{articleNO}", method = RequestMethod.PUT)
public ResponseEntity<String> modArticle(@PathVarialbe("articleNO") Integer articleNO, @RequestBody ArticleVO articleVO){
...
}
// articleNo에 해당하는 글을 삭제 - DELETE
@RequestMapping(value = "/{articleNO}", method = RequestMethod.DELETE)
public ResponseEntity<String> removeArticle(@PathVarialbe("articleNO") Integer articleNO){
...
}
}
<script>
...
$.ajax({
// 등록 시 - POST방식, /board+데이터
type: 'POST',
url: '${contextPath}/boards'
contentType: 'application/json',
data: JSON.stringfy(article),
...
});
</script>
수정과 삭제 등은 type와 url를 바꾸면 된다 😀
Comments