Android, IOS 어플리케이션 서비스를 위해 Spring Framework를 이용한 REST API Server를 만들고 있습니다.
예전에 네이버에서 제공해주는 Open API의 JSON 형태를 보니, {code="404", result="Not Found", data=""}와 같았습니다.
저또한 혼자 사용하는 API 서버를 만들지만, 위와같은 형태에 대해 고민하게 되어 이렇게 질문을 올립니다.
(1) Http Response의 헤더에 code, result에 대한 데이터를 담을 수 있는데 굳이 이렇게 하는 이유는 무엇일까요?
-
모든 서버응답에 대한 데이터포맷을 위와 같이 만들면, 확장이나 일관성 측면에서 어떤 이점이 생길까요?
- 일반적으로 Spring과 같은 Framework를 사용할경우 내부적으로 지정된 기본값으로 처리할거라 생각되는데 이 과정에서 개발자가 예상하지 못한 형태로 전달될 수 있어서 그럴까요?
- 위와 같은 데이터포맷을 만드는 이유가 code영역을 Http 응답코드에 기본적인 항목(200, 302, 404, 500)을 사용하는게 아닌 201, 202, 401 등으로 좀 더 세세하게 나누고자 하는 의도일까요?
(2) 만약, 위와같은 포맷형태를 Spring MVC Framework로 구현한다고 할 경우에 대한 질문입니다.
-
만약 단순하게 (200, 302, 404, 500)과 같은 프레임워크가 기본적으로 사용하는 응답코드라면 AOP나 Interceptor를 이용해 모든 응답을 {code="401", result="Not Permitted", data=""} 형태의 JSON으로 변환해주게끔 구현할것 같습니다. 그렇게 된다면 프로그래머는 반환되는 data의 영역만 신경쓰면 될것 같은데, controller의 메서드 하나로 예를 든다면 아래의 코드가 클라이언트에게 전달될때는 {code="200", result="OK", data="aaa"} 와 같이 변환되겠지요.
@RequestMapping("/test") public String test() { return "aaa"; }
하지만 201, 202, 401과 같은형태의 좀 더 세부적인 응답코드를 반환해야 한다면, 각 컨트롤러 메서드마다 Http Header를 지정하기 위한 객체를 파라미터에 선언하고, 반환코드를 일일이 지정해주는 한가지 방법이 떠오르고, 두번째는 AOP 및 Interceptor에서 데이터포맷을 지정하는게 아닌 아래와 같은 형태로 매 Controller Return 객체를 만들어 주어야 할 것 같습니다.
@RequestMapping("/test")
public ReturnData test() {
return new ReturnData<String>("aaa");
}
class ReturnData<T> {
int code = 200;
String result = getResult(code);
T data;
public ReturnData(int code, String result, T data) {
this.code = code;
this.result = result;
this.data = data;
}
public ReturnData(T data) {
this.data = data;
}
private String getResult(int code) {
switch (code) {
case 200:
return "OK";
// ....
}
}
먼저 굳이 세세하게 응답코드를 나눠야 하는가? 는 저도 잘 모르겠습니다. 하지만 클라이언트와 통신을 할때 요청에 대한 새로운 데이터를 정상적으로 생성했는지, 요청은 잘 전달받았지만 생성에는 실패했는지 (물론 서버에서는 Exception을 강제로 발생시켜 500에러를 리턴할 수 있겠지요) 등 좀더 효율적으로 사용할 수 있을텐데, 그렇게 사용하기 위해 응답코드를 조금씩은 구분지었을텐데라고 생각이 들어서요.
여러분들은 어떻게 생각하시나요?
3개의 의견 from SLiPP
계정이 Facebook과 연동이 안되있어서, 따로 의견추가합니다.
Facebook을 통해서 받은 답변내용은 다음과 같습니다.
-> 그렇다면 제가 본 JSON의 code라는건 Http 상태코드가 아니라 어플리케이션에서 사용하는 코드일 가능성도 있겠군요. 답변 감사드립니다.
구글링을 통해 원하는 가이드라인을 찾을 수 있었습니다.
https://stormpath.com/blog/spring-mvc-rest-exception-handling-best-practices-part-1/
-> 설명도 명료하고 예제소스를 통해 제가 궁금했던 내용이 해결됬습니다. 각각의 레이어에 영향을 주지 않으면서, RuntimeException의 객체종류를 통해서 원하는 형태로 Customizing이 가능하다는걸 알게되었습니다.
@한석봉 나도 답변을 달까하다가 망설였다. 내 개인적으로도 코드를 포함하는 방식은 그리 좋아하지 않는다.
좋은 코드를 구현하려면 좋은 코드를 많이 읽어야 하듯이 좋은 api를 설계하려면 좋은 api를 읽어보면 많은 연습이 되더라. facebook, google에서 수 많은 api들 제공하고 있으니 이 쪽 api 참고해 보면 좋겠다.
@자바지기 네!! 정말 이 분야는 재밌는게 많네요ㅎ
의견을 남기기 위해서는 SLiPP 계정이 필요합니다.
안심하세요! 회원가입/로그인 후에도 작성하시던 내용은 안전하게 보존됩니다.
SLiPP 계정으로 로그인하세요.
또는, SNS 계정으로 로그인하세요.