Envelope pattern(봉투 패턴) - Rest API Design Pattern - 삽질중인 개발자
- Envelope Pattern -
최근 점점 더 많은 서비스들이 Rest API 형태로 개발이 되고 있다.
이런 Rest API를 개발하다 보면 응답 값은 어떤 식으로 넘겨줘야 할 지에 대해서 고민을 하게 된다.
이 포스트에서는 데이터를 캡슐화하는 방법 중 하나인 Envelope Pattern에 대해서 설명한다.
우선 멤버(Member)라는 객체가 있다고 가정을 해보자.
public class Member {
private Long id;
private String name;
private int age;
}
멤버 객체를 JSON 형태로 표현을 한다면 아래와 같이 나오게 된다.
{
"id" : 1,
"username" : "홍길동",
"age" : 15
}
만약 이 멤버를 여러 명을 조회해야 하는 API를 개발한다고 생각해보자.
가장 쉽게 만들 수 있는 방법은 아래와 같이 그냥 배열에 멤버를 넣어서 JSON으로 던져주는 형태일 것이다.
[
{
"id":1,
"username":"홍길동",
"age":15
},{
"id":2,
"username":"아무개",
"age":24
},
...
{
"id":99,
"username":"개똥이",
"age":47
}
]
위에 API를 만들고 나서 작동은 잘 되니까 배포를 할 것이다.
잘 사용하고 있던 API에 조회된 멤버의 숫자를 API에 추가해달라는 요청이 왔다면 어떤 식으로 추가를 해야 할지 생각을 해보자.
바로 여기서 문제가 된다.
아무리 생각해봐도 아래처럼 memberCount를 각 멤버마다 넣어주는 방법밖에 없다.
[
{
"id":1,
"username":"홍길동",
"age":15,
"memberCount": 99
},{
"id":2,
"username":"아무개",
"age":24,
"memberCount": 99
},
...
{
"id":99,
"username":"개똥이",
"age":47,
"memberCount": 99
}
]
이렇게 되면 memberCount가 진짜 멤버가 각각 가지고 있는 값인지 아니면 조회된 멤버의 카운트인지를 알 수 없게 되며 불필요한 데이터의 중복으로 인해 네트워크 트래픽이 더 많이 발생한다.
위와 같은 상황에서 API의 확장성을 유지하기 위한 방법이 Envelope pattern이다.
Envelope pattern을 적용하게 되면 기존의 data 부분을 한번 더 레핑 해 아래와 같은 형태로 응답 데이터가 변한다.
{
"code":"success",
"data":{
"members":[
{
"id":1,
"username":"홍길동",
"age":15
},{
"id":2,
"username":"아무개",
"age":24
},
...
{
"id":99,
"username":"개똥이",
"age":47
}
]
},
"message":null
}
이러한 Envelope Pattern의 응답 형태는 딱 정해져 있는 건 아니고 보통 code, data, message 정도를 보내주며 각각의 정보에는 다음과 같은 의미가 들어가 있다.
- code : 보통 HTTP Status로 표현할 수 없는 상태 값을 보내준다.
- data : 실제 API 요청에 대한 데이터 값들이다.
- message : 보통 API 응답이 성공할 때는 null이며 에러가 발생했을 시 해당 에러에 대한 정보가 들어가 있다.
만약 앞에서 봤던 memberCount를 추가해야 하는 상황이 나오면 멤버 데이터에 추가하는 게 아니라 아래와 같이 그냥 새로운 값을 넣어주면 끝이 난다.
{
"code":"success",
"data":{
"members":[
{
"id":1,
"username":"홍길동",
"age":15
},{
"id":2,
"username":"아무개",
"age":24
},
...
{
"id":99,
"username":"개똥이",
"age":47
}
],
"memberCount" : 99
},
"message":null
}
즉, API의 확장성이 엄청나게 늘어난다.
또한 Rest API를 만들면 요청에 대한 결과 값을 HTTP Status에 담아 준다.
대부분의 경우 응답이 성공을 하면 2xx을 보낼 텐데 개발을 하다 보면 비즈니스 로직의 상태를 꼭 집어서 2xx이라고 응답하기 애매하거나 추가 설명이 더 필요한 경우가 있다.
이럴 때 미리 정의된 code 값을 같이 넘겨주면 API를 사용하는 입장에서 조금 더 명확한 상태를 알 수 있다는 장점이 생긴다.
앞으로 RestAPI 개발 시 Envelope Pattern을 사용해 조금 더 퀄리티 있는 API를 개발하자.