RESTful API 디자인. 행이 없으면 무엇을 반환해야합니까?


50

현재 Slim Framework를 사용하여 소셜 네트워크 용 API를 코딩하고 있습니다. 내 질문은 : json 구조에 반환 할 행이없는 경우 모범 사례는 무엇입니까?

이 호출 / v1 / get / movies 는 테이블 영화 이름에서 2 개의 행을 반환 한다고 가정 합니다.

[
    {"name": "Ghostbusters"},
    {"name": "Indiana Jones"}
]

그러나 / v1 / get / books를 호출 하면 해당 테이블에 행이 없습니다. 빈 구조 만 반환해야합니까?

[
]

... 또는 메시지와 오류 코드가 더 좋을까요?

[
    "errors": {
        "message": "no matches found",
        "code": 134
    }
]

더 나은 연습은 무엇입니까? (API는 iOS 및 Android 앱에서 사용됩니다) 감사합니다!


3
나에게 이것은 0이 실제로 양인지 아닌지의 질문처럼 느껴집니다.
scarfridge

16
귀하의 예가 깨졌습니다. 중복 키가있는 json 객체를 가질 수 없습니다. 찾고있는 것은 배열입니다.[{"name": "..."}, {"name":"..."}]
Martin Wickman

@MartinWickman 죄송합니다. 방금 수정했습니다.
Andres SK

8
@andufo, 실제로, 당신은하지 않았다 ...
avakar

25
애플리케이션이 RESTful 인 경우 동사 / 방법이 왜 엔드 포인트 URI의 일부가 되는가?
user50849

답변:


46

일반적으로 메타 데이터로 결과의 레코드 수를 반환합니다. 이것이 정상적인 REST 연습인지 확실하지 않지만 추가 데이터는 많지 않으며 매우 정확합니다. 일반적으로 많은 서비스에 대해 페이지 매김이 발생하므로 한 번에 큰 결과 집합을 반환하는 것은 비현실적입니다. 작은 결과 집합에 대한 페이지 매김이있을 때 개인적으로 화가납니다 . number_of_records : 0비어 있으면 빈 목록 / 배열로 반환 하고 예약하십시오 books : [].

{
    meta: {
        number_of_records : 2,
        records_per_page : 10,
        page : 0
    },
    books : [
        {id:1},
        {id:27}
    ]
}

편집 (몇 년 후) : Martin Wickman의 답변이 훨씬 낫습니다. 여기에 왜 설명이 부족합니다.

페이지 매김을 다룰 때 항상 내용의 가능성이나 순서 변경을 염두에 두십시오. 마찬가지로 첫 번째 요청은 24 개의 결과가 나오고 첫 번째 10이 반환됩니다. 그런 다음 "새 책"이 삽입되고 이제 25 개의 결과가 있지만 원래 요청의 경우 10 위로 주문됩니다. 첫 번째 사용자가 두 번째 페이지를 요청하면 "새 책"을받지 못합니다. 다음과 같은 API 호출로 전송해야하는 "요청 ID"를 제공 한 다음 "이전"결과 세트에서 다음 페이지를 반환하는 것과 같은 문제를 처리하는 방법이 있습니다.이 방법은 어떻게 든 저장되고 "요청 ID"에 연결되어야합니다. 대안은 "첫 번째 요청 이후 결과 목록이 변경되었습니다"와 같은 필드를 추가하는 것입니다.

일반적으로 가능하다면 추가 노력을 기울이고 페이지 매김을 피하십시오. 페이지 매김은 변경 될 수있는 추가 상태이며 이러한 변경 사항을 추적하면 오류가 발생하기 쉬우므로 서버와 클라이언트가 모두 처리해야하기 때문입니다.

한 번에 처리 할 데이터가 너무 많은 경우 해당 목록의 일부 청크에 대한 모든 결과 및 세부 사항과 함께 "id list"를 리턴하고 자원에 대한 multi_get / get_by_id_list API 호출을 제공하십시오.


1
허, 왜이 투표가 다른 투표만큼 투표되지 않는지 궁금합니다. 특별한 조건없이 맹목적으로 반복 할 수있는 빈 목록 (목록, 오른쪽으로 가정해야 함)을 제공함에 따라 나는 이것을 더 좋아합니다. 또한 메타 데이터는 "아니요, 우리는 t는 당신에게 오류에 대한 광택, 실제로 0 결과가 있었다 ".
이즈 카타

1
-1 books매개 변수는 객체이지만 'books'는 둘 이상의 배열을 의미하고 하나 이상의 배열을 의미합니다 메타 데이터는 훌륭하지만 결국에는 책 모음이 책 객체의 배열이 될 것으로 기대합니다. 책이 없다면 그냥 빈 배열을 줘
Charles Sprayberry

9
"number_of_records"를 추가해도 더 이상 정보가 제공되지 않고 중복성을 추가하고 복잡성을 증가시키는 문제가 있습니다. 오류를 알리려면 본문에 적절한 http 코드 + 무언가를 반환하십시오.
Martin Wickman

1
@zspray books는 Izkata가 지적한 것처럼 오타입니다.
grizwako 2014 년

2
@MartinWickman 추가 메타 데이터로 원래의 답변을 오염시키고 싶지 않았지만, 많은 경험을 통해 많은 데이터가 즉시 모든 데이터를 반환하지는 않지만 "매김 된"방식으로 반환합니다.
grizwako 2014 년

105

귀하의 예가 깨졌습니다. 중복 키가있는 json 객체가 없어야합니다. 찾고있는 것은 다음 과 같이 영화 객체 가 있는 배열 입니다.

 [
    {"name": "movie1"}, 
    {"name": "movie2"}
 ]

이 방법은 또한 귀하의 질문에 답변합니다. 쿼리 가 일치하지 않으면 빈 배열을 반환해야합니다 .

[]

반면에 특정 영화 리소스 를 얻으려고 시도 GET api/movie/34하고 해당 영화가 존재하지 않으면 본문에 적합한 (json 인코딩) 오류 메시지와 함께 404를 반환하십시오.


1
+1에 따라 유효한 JSON json_xs입니다.
l0b0

15

이것이 JSON이라면 실제로 객체 배열을 반환하는 것을 고려해야합니다. 레코드가 없을 때 빈 배열이라는 점을 포함하여 많은 장점이 있습니다.

따라서 기록이 있으면 다음을 반환합니다.

    [
        {"name": "Ghostbusters"},
        {"name": "Indiana Jones"}
    ]

그리고 당신이 기록이 없으면, 당신은 돌아올 것입니다 :

    [

    ]

14

작업을 성공적으로 실행했지만 빈 맵 {}또는 빈 배열 과 같이 반환 할 항목이없는 경우 []204 응답 코드로 응답하는 것이 좋습니다 . 여기 HTTP 상태 코드 정의 사양 에서 발췌 한 것입니다 .

서버가 요청을 이행했지만 엔티티 본문을 리턴 할 필요가 없으며 업데이트 된 메타 정보를 리턴 할 수 있습니다. 응답에는 엔티티 헤더의 형태로 새로운 메타 정보 또는 업데이트 된 메타 정보가 포함될 수 있으며, 존재하는 경우 요청 된 변형과 연관되어야합니다.

클라이언트가 사용자 에이전트 인 경우 요청을 보낸 원인에서 문서보기를 변경해서는 안됩니다. 이 응답은 주로 사용자 에이전트의 활성보기에있는 문서에 새로운 또는 업데이트 된 메타 정보를 적용해야하지만, 사용자 에이전트의 활성 문서보기를 변경하지 않고 작업에 대한 입력을 허용하기위한 것입니다.

204 응답은 메시지 본문을 포함해서는 안되므로 항상 헤더 필드 다음의 첫 번째 빈 줄로 종료됩니다.

본질적으로 반환 할 것이 없을 때 HTTP를 통한 RESTful 응용 프로그램에서 204를 사용하는 것이 좋습니다.


4
다른 답변에 대한 @avakar의 의견에 동의합니다. 클라이언트가 / v1 / get / movies / 1에 액세스하려고하면 1로 식별 가능한 영화가 없으면 404를 반환해야합니다. 영화가없는 경우에도 / v1 / get / movies는 200을 반환해야합니다. 그러나 204는 입력 작업을위한 것이므로 적합하지 않습니다.
imel96

7
이 솔루션의 또 다른 문제점은 일반적으로 클라이언트에 특수 코드가 필요하다는 것입니다. 응답이 빈 목록 인 경우 일반 응답처럼 JSON으로 구문 분석 할 수 있습니다. 응답이 비어있는 본문 인 경우 JSON 구문 분석기는 (emtpy 문서가 유효한 JSON이 아니기 때문에) 불평 할 가능성이 있으므로 클라이언트는 HTTP 204를 확인하고 구문 분석을 건너 뛰기 위해 추가 코드가 필요합니다.
sleske

7
나는 이것이 204의 의도를 잘못 읽은 것이라고 믿는다. 204는 내용을 예상하고 찾지 못한 오퍼레이션을위한 것이 아니라, 성공하고 리턴없는 오퍼레이션을 위한 것으로 보인다 . Wikipedia에서 : "서버가 요청을 성공적으로 처리했지만 컨텐츠를 리턴하지 않습니다. 일반적으로 성공적인 삭제 요청에 대한 응답으로 사용됩니다."
XML

10

표준화 된 JSON API 형식 을 만드는 데 상당한 양의 작업이있었습니다 .

이 사양의 원칙을 준수한다는 것은 반환 된 모든 리소스가 효과적으로 "컬렉션"이어야한다는 것을 의미합니다 (단일 리소스 만 포함 된 경우에도). 이를 따르면 귀하의 전화 /v1/get/movies가 돌아올 것입니다 :

{
    "movies": [
        {"name": "Ghostbusters"},
        {"name": "Indiana Jones"}
    ]
}

/v1/get/books(0 개의 리소스를 반환)에 대한 호출 은 다음을 반환합니다.

{
    "books": []
}

5

구체적인 예를 들어, / v1 / get / books는 빈 배열로 HTTP 200을 반환하는 것이 좋습니다.

게시물을 올바르게 읽으면 API가 책을 수집하려고합니다. 은유 적으로 말하면, 책을위한 책장, 영화를위한 DVD 랙 및 여기에 언급되지 않은 다른 컨테이너가 있습니다. 책을 수집하려고하므로 / v1 / get / books가 책장입니다. 이는 특정 예제에서 비어있는 유효한 리소스 (책 목록)가 있음을 의미합니다.

이 경우 HTTP 404를 반환하지 않는 이유는 서가가 여전히 있기 때문입니다. 현재 책이 없습니다 만, 여전히 책장입니다. 그것은 API -if 책장 아니었다면 예 -에 대한 책을 수집하는 의도하지 않은 다음 (404)가 적절하다 HTTP. 그러나 거기에 리소스가 있기 때문에 HTTP 404 가하는 리소스가 없다는 신호를 보내면 안됩니다. 따라서 빈 배열 (컬렉션을 나타냄)이있는 200이 더 적합하다고 주장합니다.

HTTP 204를 반환하도록 제안하지 않는 이유는 "No Content"가 일반적인 업무 상태임을 암시하기 때문입니다.이 리소스에 대해이 작업을 수행하면 일반적으로 아무것도 반환되지 않습니다. 이것이 DELETE 요청에 대한 응답으로 일반적으로 사용되는 이유입니다. 예를 들어, 삭제의 특성은 일반적으로 반환 할 항목이 없음을 의미합니다. 이 사례는 If-Modified 헤더 제품군의 요청에 응답하는 데 사용되는 경우와 비슷합니다. 리소스가 변경된 경우에만 콘텐츠를 원했지만 아직 변경하지 않았으므로 콘텐츠를 제공하지 않습니다.

그러나 비어 있지만 유효한 컬렉션을 얻으려면 HTTP 204가 의미가 없다고 주장합니다. 컬렉션에 항목이있는 경우 적절한 표현은 해당 데이터의 배열입니다. 따라서 데이터가없는 경우 (그러나 콜렉션은 유효 함) 올바른 표현은 빈 배열입니다.


5

정말 두 가지 중 하나만 수행해야합니다

200 (OK)상태 코드와 본문의 빈 배열을 반환합니다 .

또는 204 (NO CONTENT)상태 코드를 반환하고 응답 본문이 없습니다.

나에게 옵션 2는 기술적으로 더 정확하고 REST 및 HTTP 원칙에 따라 유지되는 것 같습니다.

그러나 클라이언트가 두 가지 (성공) 상태 코드를 구별하기 위해 추가 논리가 필요하지 않기 때문에 옵션 1이 클라이언트에게 더 효율적으로 보입니다. 항상 배열을 수신한다는 것을 알고 있기 때문에 아무 것도, 하나 또는 많은 항목이 있는지 확인하고 적절하게 처리해야합니다.


3

프로덕션 환경에서 두 경우를 모두 보았습니다. 어느 것을 선택할지는 API를 사용할 사람에 따라 다릅니다. 목록이 비어있는 이유를 알고 있거나 목록이 실제로 비어 있고 검색하는 동안 오류가 발생하지 않도록하려면 "errors"오브젝트를 첨부해야합니다. 걱정하지 않으면 빈 목록을 반환하십시오. 첫 번째보다 더 많은 요구를 충족시키기 때문에 두 번째 접근 방식을 사용합니다.


3

RESTful API를 빌드 중이므로 가장 먼저 고려해야 할 것은 적절한 응답 코드를 리턴하는 것입니다. 그리고 요청이 정상적으로 진행되었음을 알리는 더 적절한 응답 코드이지만 현재 요청 된 리소스를 사용할 수 없습니다.

항상 합리적인 응답 코드를 반환하는 방식으로 API를 디자인하면 리소스를 찾을 수 없을 때 본문을 반환하지 않아도됩니다. 즉, 신체, 특히 인간이 읽을 수있는 신체를 돌려주는 것은 상처를 줄 수 없습니다.

여기에 "모범 사례"는 없습니다. 두 예제 모두 임의적 입니다. 하나만 골라 일관성을 유지하십시오 . 개발자는 경우, 놀라움을 싫어 /v1/get/movies반환 {}할 때 어떤 영화가없는 우리는 기대 /v1/get/actors도 돌아 {}어떤 배우가없는 경우.


1
404를 돌려주는 것이 실제로 옳은 일이지만 슬프게도 아무도 그것을 포함하지 않습니다.
RibaldEddie

1
복잡한 응답이 있고 그 중 일부만 비어 있으면 404를 반환하면 사용자가 혼동됩니다.
devnull

5
404 메시지에 동의하지 않습니다. 404 "자원이 존재하지 않습니다"라고 해석하고 URL에 문제가 있는지 걱정합니다. 영화 목록을 요청하고 404를 얻으면 영화 리소스가 전혀 없다고 생각합니다. "204 No Content"가 더 적합 할 수 있습니다.
thorsten müller

8
좋아, "몸이없는"것은 그것을 죽일 것입니다. 그러나 "4xx 등급의 상태 코드는 클라이언트가 오류가 발생한 것처럼 보이기위한 것입니다." 그러나 클라이언트 측에는 오류가 없었습니다. 따라서 404는 잘못된 정보를 제공합니다. 본문없이 204를 보내거나 괜찮다고 말하고 빈 목록을 보내십시오.
thorsten müller

9
404를 반환하면 책 목록 이 필요합니다 . 목록 이 비어 있지 않고 존재하지 않는 것입니다. 빈 목록과 함께 200을 반환하면 나에게 유일한 합리적인 옵션 인 것 같습니다.
avakar

1

나는 rigth 답변이 표시된 답변이라고 생각하지 않습니다.

진정한 REST 시나리오에서 nirth가 제공하는 답변이 가장 좋습니다. 본문 응답은 비어 있어야하며 http 상태 코드 : 204; 리소스가 존재하지만 그 시점에 "컨텐츠 없음"이 있습니다 : 비어 있습니다.

REST HTTP_Status_Codes


1

200 + 빈 배열을 사용하는 것이 좋습니다. API의 모든 클라이언트가 처리를 단순화하기 때문입니다. 200 + 배열은 "있는 모든 데이터를 반환했습니다"를 의미합니다. 데이터를 전달하는 코드와이를 처리하는 코드 모두 항목 수와 관련이 없습니다.

다른 모든 상태 코드는 서버에서 올바르게 문서화하고 올바르게 전달하고 클라이언트가 올바르게 처리해야하며, 이러한 상황이 발생할 가능성을 모두 알고 있습니다.

상태 204 + 빈 본문을 반환하라는 제안이있었습니다. 즉, 모든 단일 클라이언트가 상태 204를 올바르게 처리하도록해야합니다. 또한 비 JSON 응답을 처리하도록 강요합니다! 요청이 응답을 받았기 때문에 http가 사용될 때 서버에서 응답이 온 것을 의미하는 것이 아니라 응답이 JSON인지 확인하는 것이 많은 경우를 처리한다는 것을 모두가 깨닫기를 바랍니다.


0

나는 "그것은 달려있다".

0이 합리적인 결과이면 빈 목록을 반환하십시오. 예를 들어, "none"이 상당히 합리적인 결과 인 "bob"이라는 모든 직원을 확보하려는 경우. 예상 한 결과가 아니면 오류를 반환합니다. 예를 들어 당신이 고용 한 사람의 과거 주소 목록을 얻는 것입니다. 그들은 어딘가에 살아야만합니다. 결과는 정상적인 상태가 아니라 오류 일 가능성이 없습니다.

나는 당신이 내 예의 세부 사항을 주장 할 수 있다고 확신하지만 아이디어를 얻습니다 ...


0
  • 우선, getURL에 포함하는 것이 RESTful하지 않으므로 GET은 HTTP 메소드에 의해 암시됩니다.
  • 빈 배열로 GET api/moviesreturn a 200 OK와 같은 컬렉션을 요청하는 경우 [].
  • GET api/movies/1( 1id가있는 곳 )과 같은 특정 영화를 요청하고 존재하지 않는 경우을 반환하십시오 404 Not Found.

왜? 자원 을 요청하고 있습니다 . 컬렉션을 요청하면 리소스 자체 (컬렉션)가 존재합니다. 따라서, 404잘못되었습니다. 그러나 특정 영화를 요청했지만 해당 영화가 존재하지 않으면 요청 된 리소스가 존재하지 않으므로를 반환해야합니다 404.


-2

JSON을 반환하는 경우 항상 count 및 error 메시지와 오류가 있거나없는 경우를 나타내는 부울을 반환하는 것이 좋습니다. 즉, 각 행 목록과 함께 반환되는 표준 3 개의 메타 값입니다.

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