REST API-API가 중첩 JSON 객체를 반환해야합니까?


37

JSON API와 관련하여 응답을 평평하게하고 중첩 된 JSON 객체를 피하는 것이 좋습니다.

예를 들어 IMDb와 유사하지만 비디오 게임용 API가 있다고 가정하겠습니다. 게임 및 플랫폼을 매핑하는 몇 가지 엔티티 인 Game, Platform, ESRBRating 및 GamePlatformMap이 있습니다.

/ game / 1을 요청하여 ID가 ​​1 인 게임을 가져오고 플랫폼과 esrbRating이 중첩 된 게임 객체를 반환한다고 가정 해 보겠습니다.

{
  "id": 1,
  "title": "Game A",
  "publisher": "Publisher ABC",
  "developer": "Developer DEF",
  "releaseDate": "2015-01-01",
  "platforms": [
    {"id":1,"name":"Xbox"},
    {"id":2,"name":"Playstation"}
  ],
  "esrbRating": {
    "id": 1,
    "code": "E",
    "name": "Everyone"
  }
}

JPA / Hibernate와 같은 것을 사용하는 경우 FETCH.EAGER로 설정된 경우 자동으로이를 수행 할 수 있습니다.

다른 옵션은 단순히 API를 작성하고 더 많은 엔드 포인트를 추가하는 것입니다.

이 경우 / game / 1이 요청되면 게임 오브젝트 만 반환됩니다.

{
  "id": 1,
  "title": "Game A",
  "publisher": "Publisher ABC",
  "developer": "Developer DEF",
  "releaseDate": "2015-01-01",
}

플랫폼 및 / 또는 ESRBRating을 원하면 다음을 호출해야합니다.

/ game / 1 / 플랫폼 / game / 1 / esrb

이 방법은 클라이언트가 필요로하는 데이터와 필요할 때에 따라 서버에 여러 번 더 호출 할 수있는 것처럼 보입니다.

당신이 이것과 같은 것을 가질 수있는 마지막 생각이있었습니다.

{
  "id": 1,
  "title": "Game A",
  "publisher": "Publisher ABC",
  "developer": "Developer DEF",
  "releaseDate": "2015-01-01",
  "platforms": ["Xbox","Playstation"]
}

그러나 이것은 ID 나 다른 플랫폼 정보와 관련된 정보가 필요하지 않다고 가정합니다.

API에서 반환 된 JSON 객체를 구성하는 가장 좋은 방법은 무엇인지 일반적으로 묻습니다. 가능한 한 엔터티에 가까이 접근해야합니까, 아니면 도메인 개체 또는 데이터 전송 개체를 사용하는 것이 좋습니다? 데이터 액세스 계층에 대한 더 많은 작업이나 클라이언트에 대한 더 많은 작업 중 하나의 방법으로 트레이드 오프가 발생한다는 것을 알고 있습니다.

또한 JPA / Hibernate 또는 MyBatis를 사용하여 API의 백엔드 기술로 Spring MVC를 사용하는 것과 관련된 답변을 듣고 싶습니다.


6
임베드 된 오브젝트를 리턴하는 경우 어떤 이의가 있습니까? 다른 엔드 포인트에서 개별적으로 내장 된 객체를 반환하면 상당히 성가 시게됩니다 (느리게 언급하지 않아도 됨).
Robert Harvey

1
개인적으로 나는 이에 반대하지 않습니다. 모범 사례로 간주되는 사항을 알지 못합니다. 동료가 AngularJS에 포함 된 객체로 작업하는 것은 간단하지 않으며 결국에는 Ember of AngularJS 앱이 API를 소비하기를 원합니다. Angular 또는 Ember에 대해 영향을 줄지 여부를 알 수 없습니다.
greyfox

3
답은 도메인 객체, DTO, ViewModel 객체 또는 KitchenSink 객체를 반환할지 여부에 따라 달라집니다. 어떤 객체를 반환하는지는 응용 프로그램의 요구 사항과 해당 객체가 인터넷을 통해 어떻게 동작하는지에 따라 결정될 가능성이 큽니다. 예 : 인보이스의 데이터로 웹 페이지를 채우려 고하는 경우 광고 항목 등에서 AJAXing을 계획하지 않는 한 필요한 모든 것을 포함하는 개체를 반환 할 가능성이 높습니다.
Robert Harvey

이 경우 게임을 요청할 때 장르, 플랫폼 및 ESRBRating을 알고 싶을 것입니다. 말이 되네요 Java 관점에서의 디자인 측면에서 JPA 엔터티가있는 Entity 패키지와 비즈니스 오브젝트 / DTO 인 도메인 패키지가 사용자에게 리턴되도록하는 것이 좋습니다.
greyfox

1
서버 호출 비용이 비쌉니다. 여러 호출을 사용하여 데이터를 보내야하는 API는 API가 필요없는 정보를 반환 할 때도 한 번의 호출로 모든 것을 가져올 수있는 API보다 느립니다.
로봇 고트

답변:


11

다른 대안 (HATEOAS 사용). 이것은 간단합니다. 대부분의 경우 실제로 HATEOAS 사용에 따라 json에 링크 태그를 추가합니다.

http://api.example.com/games/1:

{
  "id": 1,
  "title": "Game A",
  "publisher": "Publisher ABC",
  "developer": "Developer DEF",
  "releaseDate": "2015-01-01",
  "platforms": [
    {"_self": "http://api.example.com/games/1/platforms/53", "name": "Playstation"},
    {"_self": "http://api.example.com/games/1/platforms/34", "name": "Xbox"},
  ]
}

http://api.example.com/games/1/platforms/34:

{
  "id": 34,
  "title": "Xbox",
  "publisher": "Microsoft",
  "releaseDate": "2015-01-01",
  "testReport": "http://api.example.com/games/1/platforms/34/reports/84848.pdf",
  "forms": [
    {"type": "edit", "fields: [] },
  ]
}

물론 모든 목록에 모든 데이터를 포함시킬 수는 있지만 너무 많은 데이터가 될 수 있습니다. 이 방법을 사용하면 필요한 데이터를 포함시킨 다음 실제로 작업하려는 경우 더 많은 데이터를로드 할 수 있습니다.

기술 구현에는 캐싱이 포함될 수 있습니다. 게임 오브젝트에 플랫폼 링크 및 이름을 캐시하고 플랫폼 API를 전혀로드하지 않고도 즉시 전송할 수 있습니다. 그런 다음 필요할 때로드 할 수 있습니다.

예를 들어 양식 정보를 추가 한 것을 알 수 있습니다. 게임 목록에로드하려는 것보다 자세한 json 객체에 훨씬 더 많은 정보가 있음을 보여주기 위해 그렇게했습니다.


상태가 없기 때문에 기술적으로 HATEOS라고 생각하지 않습니다.
RibaldEddie

예,이 과정에 대한 정확한 단어는 확실하지 않습니다. 일반적으로 HATEOS는 나머지 API에서 연결하는 데 사용되지만 상태와 관련이 있음에 동의합니다. 구현 아이디어는 동일하지만. 다음은 예제에서 어떻게 사용할 수 있는지에 대한 약간의 내용입니다. stormpath.com/blog/linking-and-resource-expansion-rest-api-tips
Luc Franken

그래도 좋은 생각입니다!
RibaldEddie

1
클라이언트와 api 자체 (예 : 내부 api) 사이에 응집력이있는 API를 개발하는 경우 다른 리소스에 대한 링크를 제공하는 것보다 중첩 된 (또는 평탄화 된) 응답을 반환하는 것이 더 합리적 일 수 있습니다. 이는 더 많은 API 요청을 의미합니다 바람직하지 않을 수 있습니다.
Bruno

@bruno 예. 그러나 제한이 있습니다. 더 큰 시스템에서는 모든 관련 개체를 모두 제공 할 수 없거나 원하지 않습니다. 기본적으로 포함하는 필드는 임의적이며 API 사용에 따라 선택할 수 있습니다. 따라서이 경우 수백 개의 필드가있는 플랫폼이있을 수 있으며 유스 케이스에는 플랫폼을 선택하기위한 선택 상자가 표시됩니다. 그런 다음 플랫폼 이름을 포함시키는 것이 합리적이지만 예를 들어 플랫폼의 재무 세부 정보는 필요하지 않습니다.
Luc Franken

16

이것은 REST API 디자인과 관련하여 기본적인 질문 중 하나입니다. 모든 디자이너는 첫날에이 질문을합니다. 죄송하지만 답변은 "의존"입니다. 각 접근 방식에는 장단점이 있으며 결정을 내리고 진행하면됩니다.


10
이것은 전혀 도움이되지 않습니다. OP 자신도 "의지가 있으며 각 방법마다 장단점이 있습니다"를 알고있었습니다. 어떤 것이 의존하는지 또는 최소한 예를 들어 설명해야합니다.
Pratik Singhal

5

https://www.slideshare.net/stormpath/rest-jsonapis에 제시된 접근 방식은 두 번째입니다.

즉, 중첩 된 자원을 상위 자원의 링크로 포함하는 한편 상위 엔드 포인트에서 확장 매개 변수를 제공하십시오.

제 생각에는 이것이 대부분의 경우 효율적이고 유연한 방법입니다.


2
나는이 접근법을 좋아한다. 궁금하신 분은 링크 된 슬라이드 쇼의 SLIDE 57에서 시작합니다.
Adam Plocher
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.