RESTful API에서 배열을 응답으로 반환하는 가장 좋은 방법은 무엇입니까?


40

이와 같은 리소스가 있다고 가정 해 봅시다.

book:
    type: object
    properties:
        author: {type: string}
        isbn: {type: string}
        title: {type: string}

books:
    type: array
    items: book

누군가가 GET책 리소스를 만들면 다음을 반환합니다.

[{"author": "Dan Brown", "isbn": "123456", "title": "Digital Fortress"},
 {"author": "JK Rowling", "isbn": "234567", "title": "Harry Potter and the Chamber of Secrets"}]

직장에서 누군가에게 권장되는 REST 사례는 항상 응답을 JSON 객체로 반환하는 것이라고 들었습니다 books.

books:
    type: object
    properties:
        list:
            type: array
            items: book

이제 응답은 다음과 같습니다.

{
    "list": [{"author": "Dan Brown", "isbn": "123456", "title": "Digital Fortress"},
             {"author": "JK Rowling", "isbn": "234567", "title": "Harry Potter and the Chamber of Secrets"}]
}

다음 중 가장 좋은 REST 방법은 무엇입니까?


1
JSON RESTful입니까? 반드시 html을 반환해야합니까?
Ewan

3
@Ewan : 페이로드는 중요하지 않습니다. 이것이 바로 MIME 형식입니다.
Robert Harvey

1
REST에 대한 모범 사례도 아닙니다. REST는 HATEOAS로 만들어져 API의 검색 가능성을 의미합니다. HAL 또는 JSON-LD를 찾으십시오.
Florian Margaine 2016 년

Json-ld : WCF를 향한 천천히 노력
Ewan

내가 읽은 객체에서 JSON 배열을 래핑하는 것은 오래된 브라우저 -haacked.com/archive/2009/06/25/json-hijacking.aspx 에서보고 된 취약점에 대한 방어 조치 입니다. 이것은 오늘날의 현대 브라우저에서 해결 된 것으로 보입니다. 미안보다 안전합니다 ..
Gishu

답변:


35

실제로 두 번째 옵션은 모범 사례입니다. 그 이유는 배열을 반환 할 때 리소스를 전혀 확장 할 수 없기 때문입니다.

예를 들어 : 모든 레코드 수를 추가해야하는 경우 이미 배열 전용 방법으로 수행 된 것입니다.

그것이 하나의 목록 api에서 발생하면 일관성을 유지하기 위해 모든 객체를 만들면 API 가보다 일관되고 개발자가 더 쉽게 사용할 수 있습니다.

예를 들어, 개발자가 API를 사용하여 목록 및 세부 정보 페이지를 표시하는 일반 코드를 작성한다고 가정 해 보겠습니다. 그는 때로는 배열이고 때로는 목록 속성을 가진 객체이기 때문에 예외를 만들고 싶지 않습니다.

이 답변은 전체적으로 휴식, 증오 및 기타 프로토콜에 관한 원칙과는 아무런 관련이 없지만 고객에게 보내야하는 데이터에 대해서는 실제로 존재합니다. 예를 들어 hateos를 따르기로 결정했다면 오프 코스 표준 (또한 객체 btw)을 고수하십시오.


3
"실제 데이터에 대해"+1 (그리고 REST에 대한보다 기술적이고 정확한 정의가 있음을 인식하면서) +1
THREED

8

양자 모두

[{"author": "Dan Brown", "isbn": "123456", "title": "Digital Fortress"},{"author": "JK Rowling", "isbn": "234567", "title": "Harry Potter and the Chamber of Secrets"}]

{
    "list": [{"author": "Dan Brown", "isbn": "123456", "title": "Digital Fortress"},
         {"author": "JK Rowling", "isbn": "234567", "title": "Harry Potter and the Chamber of Secrets"}]
}

유효한 Json입니다. 필요하지 않은 경우 "목록"을 추가해야한다고 생각하지 않습니다. 다음에 오는 것이 목록이 아니라 배열이기 때문에 혼란 스러울 수도 있습니다.

최고의 REST 연습? API는 Accept 헤더에 설정된 내용에 대한 적절한 응답과 좋은 문서를 제공해야합니다.


7

응답 JSON을 준수하게 만드는 이유는 JSON이 사실상 표준 이기 때문입니다 . JSON 구문 분석기가있는 모든 언어는 사소하게 구문 분석 할 수 있으며 JavaScript를 사용하는 경우 JavaScript가 기본적으로 이해하므로 구문 분석기가 필요하지 않습니다.

즉, JSON과 호환되도록하고 고유 한 구문 분석기를 작성할 필요가 없습니다. 또한 다음 개발자가 서비스를 사용하는 소프트웨어를 작성할 때 놀라운 일은 없을 것입니다.

REST는 JSON 스키마와 관련이 없습니다. REST 관점에서 스키마 중 하나를 사용할 수 있습니다.


9
그 질문에 대답합니까? "json 배열이나 json 객체를 루트로 사용해야합니까?"라고 읽었습니다. 둘 다 json 파서로 파싱 할 수 있으므로 귀하의 대답은 그들이 결정하는 데 도움이되지 않습니다.
코드 InChaos

그런 다음 중요하지 않습니다. 내 답변을 업데이트했습니다.
Robert Harvey

REST에 관해 이야기하고 있다면, 스키마는 응답만을 기반으로 추가 자원을 발견하고 조작하기위한 하이퍼 미디어 제어를 제공 할 수 있고 다른 대역 외 정보는 제공하지 않는 한 중요하지 않습니다. OP가 언급 한 형식 중 어느 것도 수행하지 않는 것 같습니다.
toniedzwiedz

...and if you're using JavaScript, you don't even need a parser since JavaScript understands it natively.예, 아니오 JSON은 JavaScript의 하위 집합이지만 eval파서를 사용하는 대신 호출 하면 즉시 악의적 인 코드가 포함 된 "JSON"에 취약 해지며 구문 분석은 가장 효율적 eval입니다.
Doval

5

의미없는 단일 키 "목록"과 배열 값을 가진 사전은 의미가 없습니다. 대신 배열을 반환하십시오.

동일한 서비스가 서적, CD 또는 DVD를 리턴 할 수있는 경우 키 "books"및 배열 값을 가진 사전을 리턴 할 수 있습니다. DVD 배열을 가진 또 다른 키 "DVD"가있을 수 있습니다. 예를 들어 고객이 모든 구매 목록을 조회 할 수있는 경우입니다.

응답이 책 목록으로 만 해석 될 것이 확실하다면 (요청에 "도서 목록 제공"이라고 말한 경우) 배열 만 있으면됩니다.


5

두 번째 옵션은 보안상의 이유로 선호되는 방법이기도합니다. 오래된 브라우저에는 웹 페이지의 다른 자바 스크립트 코드가 JSON 배열로 반환되는 경우 데이터를 훔칠 수있는 보안 취약점이 있습니다. 역사적으로 가장 좋은 방법은 JSON 배열을 반환하지 않는 것입니다. 실제로 배열을 전달할 때 "json-ify"함수가 기본적으로 옵션 2를 선택하는 일부 프레임 워크가있었습니다.

https://stackoverflow.com/questions/3503102/what-are-top-level-json-arrays-and-why-are-they-a-security-risk

http://ejohn.org/blog/re-securing-json/


1

둘 다 json이며 REST를 준수합니다. 귀하의 사례 변경 목록에서 책에 대한 답변을보다 자세하게 설명하겠습니다. 또는 이와 같은 것 :

{ "responceObject" : {

   results : 2,

    "Books": [
        {"author": "Dan Brown", "isbn": "123456", "title": "Digital Fortress"},
        {"author": "JK Rowling", "isbn": "234567", "title": "Harry Potter and the Chamber of Secrets"}
    ]

}}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.