본문 바로가기

기타

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를 개발하자.

 

 

 

 

 

 

반응형