저번 포스트에선 REST에 대한 공부를 하고 왔는데요.
이번 포스트에선 직접 코드를 작성해보며 실제 사용할 수 있도록 해볼거에요.
이전 프로젝트에 REST의 설계 원칙을 지키지 못한채 JSON 데이터 통신을 구현한 코드가 있어요. 이 코드를 RESTful 하게 설계해볼게요.
(위와 같은 과도기적 상태인 코드가 나오게 된 상황을 말해보자면요. 모달팝업창을 이용해서 데이터를 수정해야하는데 수정을 위해 기존 데이터를 불러와야 하는 상황이었어요. 모달팝업창으로 수정해야하기 때문에 SSR방식의 model 객체는 사용할 수 없었어요. 그래서 고민 끝에 나온 방법이 순수한 데이터만 보내는 방식이었어요.)
Backend(Java/Spring MVC)
// RESTful 하지 않은 기존 코드
@Controller
@RequestMapping("/teacher")
public class TeacherController {
@RequestMapping(value = "/subject/subject_update.do", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
@ResponseBody
public String SubjectUpdate(int uno, int sno) {
SubjectVO vo = teacherService.SubjectSearch(uno, sno);
return ConvertUtil.toJson(vo);
}
}
// RESTful 하게 변환한 코드
@RestController
@RequestMapping("/subjects")
public class TeacherController {
@GetMapping("/{sno}")
public SubjectVO getSubject(@PathVariable int sno, @RequestParam int uno) {
return teacherService.SubjectSearch(uno, sno);
}
}
위의 변환한 코드들을 순서대로 하나씩 뜯어볼게요!
1. @Controller -> @RestController
: @RestController를 사용하면 @ResponsBody를 사용하지 않아도 돼요!
2. @RequestMapping("/teacher") -> @RequestMapping("/subjects")
: 기존 코드에서는 뷰까지 한번에 보내줘야하는데 다른 폴더에 같은 이름의 파일이 있어서 폴더로 구분을 해줘야 했어요. 하지만 RESTful 한 코드에서 서버는 데이터를 주기만 하는 역할이기 때문에 그럴필요가 없어요. 그리고 RESTful에서 서버는 많은 데이터를 갖고 있기 때문에 복수형으로 명시해줘야해요.
3. method, produces, charset의 유무
: method는 이제 행동을 표시하는 ajax에서 표현해줄거에요. produces와 charset은 기존에 return type이 String으로 되어있기 때문에 브라우저가 어떤 형식인지 알 수 있도록 명시해준거예요.
하지만 RESTful 한 코드에서는 객체를 보내면 maven의 jackson 라이브러리의 도움을 받아 JSON으로 변형해서 데이터를 전송해요.
4. GetMapping("/{sno}")
: 이전 포스트에 알려드린 'HTTP Method'를 용도에 따라 Mapping 앞에 작성해서 사용하면 돼요. () 안의 데이터는 URL 파라미터이RH @PathVariable로 사용할 수 있어요.
Frontend(JavaScript/AJAX)
// RESTful 하지 않은 기존 코드
function DoUpdate(sno, uno) {
$.ajax({
url: "subject_update.do",
type: "post",
dataType: "json",
data: {
uno: uno,
sno: sno
},
success: function(subject) {
},
error: function(xhr, status, error) {
}
});
}
// RESTful 하게 변환한 코드
function DoUpdate(sno, uno) {
$.ajax({
url: `/subjects/${sno}?uno=${uno}`,
type: "GET",
dataType: "json",
success: function(subject) {
},
error: function(xhr, status, error) {
}
});
}
위의 코드도 비교해서 설명해볼게요.
1. url : "subject_update.do" -> `/subjects/${sno}?uno=${uno}`
: type이 GET으로 바뀌었으니 형식에 맞게 data{}를 삭제하고 URL 파라미터와 쿼리 스트링 형식에 맞게 작성해주면 돼요.
type에는 행동을 나타내는 HTTP Method를 의도에 맞게 작성하면 돼요.
그리고 큰따옴표가 백틱으로 바꼈죠? 자바스크립트에서는 템플릿 리터럴이라는 기능을 사용하는데 `(백틱)과 ${}(플레이스홀더)를 사용해서 적용해서 가독성을 증가시킬 수 있어요.
(ex. 큰따옴표 사용 시 : "/subject/" + sno + "?uno=" + uno)
실제 구현(VS Code/Spring Boot)
실제 구현을 위해 setting 하는 방법은 내용이 길어져서 따로 포스팅하겠습니다.
lombok, fetch를 설명하기엔 길고 그냥 쓰기엔 혼선이 있을 것 같아 이것 또한 따로 포스팅하겠습니다.
프론트엔드에서 버튼을 누르면 DoUpdate 함수가 동작하며 controller 파일의 url주소에 해당하는 메서드를 동작합니다. fetch를 사용하여 script 없이 가볍게 동작가능합니다.
브라우저에서 GET 타입을 받아 해당하는 메서드가 동작합니다.
테스트 용도이기 때문에 DB를 거치지 않고 가짜 데이터를 이용하여 VO 객체에 데이터를 담습니다.
데이터를 담은 VO 객체 구성입니다. Lombok을 사용하여 더 간결하게 표현할 수 있습니다.
위에서 작성한 로직대로 구현되는 것을 볼 수 있습니다. 빨간색 동그라미의 Content-Type의 정보로 서버에서 JSON으로 데이터를 받은 것을 확인할 수 있습니다.