본문 바로가기

개발

[REST API] 리스트를 JSON으로 반환할 때 주의할 점

강의를 보다가 REST API에서 리스트를 JSON 형태로 반환할 때 주의할 점을 새롭게 알게되어 정리해두겠습니다.

1. 문제 상황

간단하게 Person class를 작성하고, List<Person>을 반환하는 API를 작성해보겠습니다. 

 

@RestController
@RequiredArgsConstructor
public class MemberController {
    @GetMapping("/api/people")
    public List<Person> getMembers(){
        Person person1 = new Person(1L, "david");
        Person person2 = new Person(2L, "messi");

        List<Person> list = new LinkedList<>();
        list.add(person1);
        list.add(person2);

        return list;
    }

    @Data
    @AllArgsConstructor
    public class Person{
        private Long id;
        private String name;

    }
}

데이터도 임시로 넣어서 반환하는 간단한 API입니다.

 

이렇게 반환할 경우, 반환 형태는 다음과 같습니다. 

 

[
    {
        "id": 1,
        "name": "david"
    },
    {
        "id": 2,
        "name": "messi"
    }
]

언뜻보면 데이터가 잘 넘어온 것 같지만, JSON 객체가 아니라 JSON 배열이 넘어오고 있습니다.

 

이보다는 다음과 같은 형태가 바람직합니다.

{
	data: [
        {
            "id": 1,
            "name": "david"
        },
        {
            "id": 2,
            "name": "messi"
        }
	]
}

제대로 된 JSON 객체 구조를 갖추게 되었고, 이렇게 하면 카운트 같은 값을 추가 할때도 그냥 key를 하나 더 추가하면 되죠.

 

그럼 실제로 count를 함께 반환하도록, API를 수정해보겠습니다. 

수정한 코드는 아래와 같습니다.

@RestController
@RequiredArgsConstructor
public class MemberController {
    @GetMapping("/api/people")
    public MembersResponse getMembers(){
        Person person1 = new Person(1L, "david");
        Person person2 = new Person(2L, "messi");

        List<Person> list = new LinkedList<>();
        list.add(person1);
        list.add(person2);


        return new MembersResponse(list.size(), list);
    }

    @Data
    @AllArgsConstructor
    public class MembersResponse{
        private int count;
        private List<Person> data;
    }

    @Data
    @AllArgsConstructor
    public class Person{
        private Long id;
        private String name;

    }
}

MemberResponse라는 DTO에 삽입 후 반환한 것처럼, 반환 전에 반환 형태로 감싼 후에 반환하면 됩니다.

 

이제 다시 API를 테스트 해보면 JSON 객체 형태로 반환되는 것을 확인할 수 있습니다.

{
    "count": 2,
    "data": [
        {
            "id": 1,
            "name": "david"
        },
        {
            "id": 2,
            "name": "messi"
        }
    ]
}