programing tip

REST 이해 : 동사, 오류 코드 및 인증

itbloger 2020. 10. 3. 10:05
반응형

REST 이해 : 동사, 오류 코드 및 인증


PHP 기반 웹 애플리케이션, 데이터베이스 및 CMS의 기본 기능을 API로 래핑하는 방법을 찾고 있습니다.

나는 주변을 둘러 보았고 여러 "스켈레톤"프레임 워크를 발견했습니다. 내 질문에 대한 답변 외에도 매우 가볍기 때문에 내가 좋아하는 REST 프레임 워크 인 Tonic 이 있습니다.

저는 REST가 가장 단순하기 때문에 REST를 선호하며이를 기반으로 API 아키텍처를 만들고 싶습니다. 나는 기본 원칙에 대해 머리를 돌리려고 노력하고 있지만 아직 완전히 이해하지 못했습니다. 따라서 많은 질문이 있습니다.

1. 내가 이해하고 있는가?

리소스 "사용자"가 있다고 가정합니다. 다음과 같이 여러 URI를 설정할 수 있습니다.

/api/users     when called with GET, lists users
/api/users     when called with POST, creates user record
/api/users/1   when called with GET, shows user record
               when called with PUT, updates user record
               when called with DELETE, deletes user record

이것이 지금까지 RESTful 아키텍처의 올바른 표현입니까?

2. 더 많은 동사가 필요합니다

이론적으로는 생성, 업데이트 및 삭제만으로 충분할 수 있지만 실제로는 더 많은 동사가 필요합니다. 나는 이것이 업데이트 요청에 포함될 있다는 것을 알고 있지만 특정 반환 코드를 가질 수있는 특정 작업이므로 모두 하나의 작업에 던지고 싶지 않습니다.

사용자 예제에서 떠오르는 일부는 다음과 같습니다.

activate_login
deactivate_login
change_password
add_credit

RESTful URL 아키텍처와 같은 작업을 어떻게 표현합니까?

내 본능은 다음과 같은 URL에 대한 GET 호출을 수행하는 것입니다.

/api/users/1/activate_login 

상태 코드를 다시 기대하십시오.

하지만 이는 HTTP 동사를 사용한다는 생각과는 다릅니다. 어떻게 생각해?

3. 오류 메시지 및 코드를 반환하는 방법

REST의 아름다움 중 큰 부분은 표준 HTTP 메서드 사용에서 비롯됩니다. 오류가 발생하면 3xx, 4xx 또는 5xx 오류 상태 코드가있는 헤더를 내 보냅니다. 자세한 오류 설명은 본문을 사용할 수 있습니다 (맞습니까?). 여태까지는 그런대로 잘됐다. 그러나 무엇이 잘못되었는지 (예 : "데이터베이스에 연결하지 못함"또는 "데이터베이스 로그인이 잘못됨") 자세히 설명 하는 독점 오류 코드 를 전송하는 방법 은 무엇입니까? 메시지와 함께 본문에 넣으면 나중에 파싱해야합니다. 이런 종류의 표준 헤더가 있습니까?

4. 인증 방법

  • REST 원칙을 따르는 API 키 기반 인증은 어떻게 생겼습니까?
  • REST 원칙을 노골적으로 위반하는 것 외에 REST 클라이언트를 인증 할 때 세션 사용에 대한 강점이 있습니까? :) (여기에서 반만 농담입니다. 세션 기반 인증은 기존 인프라에서 잘 작동합니다.)

며칠 늦게이 질문을 발견했지만 약간의 통찰력을 추가 할 수 있다고 생각합니다. 이것이 귀하의 RESTful 벤처에 도움이되기를 바랍니다.


포인트 1 : 내가 이해하고 있는가?

당신은 옳게 이해했습니다. 이는 RESTful 아키텍처의 올바른 표현입니다. 명사와 동사를 정의하는 데 매우 유용한 Wikipedia 의 다음 매트릭스를 찾을 수 있습니다 .


다음과 같은 컬렉션 URI를 다룰 때 :http://example.com/resources/

  • GET : 추가 탐색을 위해 구성원 URI와 함께 컬렉션 구성원을 나열합니다. 예를 들어, 판매 할 모든 자동차를 나열하십시오.

  • PUT : "전체 컬렉션을 다른 컬렉션으로 교체"로 정의됩니다.

  • POST : 컬렉션에서 ID가 자동으로 할당되는 컬렉션에 새 항목을 만듭니다. 생성 된 ID는 일반적으로이 작업에서 반환되는 데이터의 일부로 포함됩니다.

  • DELETE : "전체 컬렉션 삭제"로 정의됩니다.


다음과 같은 멤버 URI를 다룰 때 :http://example.com/resources/7HOU57Y

  • GET : 적절한 MIME 유형으로 표현 된 컬렉션의 주소 지정된 멤버의 표현을 검색합니다.

  • PUT : 컬렉션의 주소가 지정된 구성원을 업데이트하거나 지정된 ID로 만듭니다.

  • POST : 주소가 지정된 구성원을 자체적으로 컬렉션으로 취급하고 새 하위 구성원을 만듭니다.

  • DELETE : 컬렉션의 주소가 지정된 구성원을 삭제합니다.


포인트 2 : 더 많은 동사가 필요합니다

일반적으로 더 많은 동사가 필요하다고 생각하면 실제로 리소스를 다시 식별해야 함을 의미 할 수 있습니다. REST에서는 항상 리소스 또는 리소스 모음에 대해 작업합니다. 리소스로 선택하는 것은 API 정의에 매우 중요합니다.

로그인 활성화 / 비활성화 : 새 세션을 생성하는 경우 "세션"을 리소스로 고려할 수 있습니다. 새 세션을 만들려면 http://example.com/sessions/본문의 자격 증명과 함께 POST를 사용합니다 . 만료하려면 PUT 또는 DELETE (세션 기록을 유지할 것인지 여부에 따라 다름)를 http://example.com/sessions/SESSION_ID.

비밀번호 변경 : 이번에는 자원이 "사용자"입니다. http://example.com/users/USER_ID본문의 이전 암호와 새 암호 사용하려면 PUT가 필요합니다 . "사용자"리소스에 대해 작업하고 있으며 암호 변경은 단순히 업데이트 요청입니다. 관계형 데이터베이스의 UPDATE 문과 매우 유사합니다.

내 본능은 다음과 같은 URL에 대한 GET 호출을 수행하는 것입니다. /api/users/1/activate_login

이것은 매우 핵심적인 REST 원칙 인 HTTP 동사의 올바른 사용에 위배됩니다. 모든 GET 요청은 부작용을 남기지 않아야합니다.

예를 들어 GET 요청은 데이터베이스에서 세션을 생성하거나 새 세션 ID로 쿠키를 반환하거나 서버에 잔류 물을 남겨서는 안됩니다. GET 동사는 데이터베이스 엔진의 SELECT 문과 같습니다. GET 동사가있는 모든 요청에 ​​대한 응답은 정적 웹 페이지를 요청할 때와 마찬가지로 동일한 매개 변수로 요청 될 때 캐시 가능해야합니다.


포인트 3 : 오류 메시지 및 코드를 반환하는 방법

4xx 또는 5xx HTTP 상태 코드를 오류 범주로 고려하십시오. 본문의 오류를 자세히 설명 할 수 있습니다.

데이터베이스 연결 실패 : / 잘못된 데이터베이스 로그인 : 일반적으로 이러한 유형의 오류에는 500 오류를 사용해야합니다. 이것은 서버 측 오류입니다. 클라이언트는 잘못한 것이 없습니다. 500 개의 오류는 일반적으로 "재시도 가능"으로 간주됩니다. 즉, 클라이언트는 정확히 동일한 요청을 재 시도 할 수 있으며 서버의 문제가 해결되면 성공할 것으로 기대합니다. 본문에 세부 사항을 지정하여 클라이언트가 우리 인간에게 컨텍스트를 제공 할 수 있도록하십시오.

다른 범주의 오류는 일반적으로 클라이언트가 뭔가 잘못했음을 나타내는 4xx 제품군입니다. 특히이 오류 범주는 일반적으로 요청이 영구적으로 실패하기 때문에 요청을있는 그대로 재 시도 할 필요가 없음을 클라이언트에 나타냅니다. 즉, 클라이언트는이 요청을 재 시도하기 전에 무언가를 변경해야합니다. 예를 들어 "리소스를 찾을 수 없음"(HTTP 404) 또는 "잘못된 요청"(HTTP 400) 오류가이 범주에 속합니다.


포인트 4 : 인증 방법

포인트 1에서 지적했듯이 사용자를 인증하는 대신 세션 생성에 대해 생각할 수 있습니다. 적절한 HTTP 상태 코드 (200 : 액세스 허용 또는 403 : 액세스 거부)와 함께 새 "세션 ID"가 반환됩니다.

그런 다음 RESTful 서버에 "이 세션 ID에 대한 리소스를 얻을 수 있습니까?"라고 물을 것입니다.

인증 모드가 없습니다. REST는 상태 비 저장입니다. 세션을 생성하고이 세션 ID를 매개 변수로 사용하여 서버에 리소스를 제공하도록 요청하고 로그 아웃시 세션을 삭제하거나 만료합니다.


간단히 말해서, 당신은 이것을 완전히 뒤로하고 있습니다.

사용해야하는 URL에서 접근해서는 안됩니다. 시스템에 필요한 리소스와 해당 리소스를 나타내는 방법, 리소스와 애플리케이션 상태 간의 상호 작용을 결정하면 URL은 사실상 "무료"로 제공됩니다.

Roy Fielding 을 인용하려면

REST API는 리소스를 나타내고 애플리케이션 상태를 구동하는 데 사용되는 미디어 유형을 정의하거나 기존 표준 미디어 유형에 대한 확장 된 관계 이름 및 / 또는 하이퍼 텍스트 사용 마크 업을 정의하는 데 거의 모든 설명 작업을해야합니다. 관심있는 URI에서 사용할 방법을 설명하는 데 소요 된 모든 노력은 미디어 유형에 대한 처리 규칙 범위 내에서 완전히 정의되어야합니다 (대부분의 경우 기존 미디어 유형에 의해 이미 정의 됨). [여기서 실패는 대역 외 정보가 하이퍼 텍스트 대신 상호 작용을 유도한다는 것을 의미합니다.]

사람들은 항상 URI로 시작하고 이것이 해결책이라고 생각하며 REST 아키텍처의 핵심 개념을 놓치는 경향이 있습니다. 특히 위에서 인용 한 것처럼 "여기서 실패는 대역 외 정보가 하이퍼 텍스트 대신 상호 작용을 주도하고 있음을 의미합니다. "

솔직히 말해서 많은 사람들은 많은 URI와 일부 GET, PUT 및 POST를보고 REST가 쉽다고 생각합니다. REST는 쉽지 않습니다. RPC over HTTP는 쉽고 HTTP 페이로드를 통해 프록시 된 데이터 blob을 쉽게 이동할 수 있습니다. 그러나 REST는 그 이상입니다. REST는 프로토콜에 구애받지 않습니다. HTTP는 매우 인기 있고 REST 시스템에 적합합니다.

REST는 미디어 유형, 정의 및 애플리케이션이 하이퍼 텍스트 (효과적으로 링크)를 통해 해당 리소스에 사용할 수있는 작업을 구동하는 방법에 있습니다.

REST 시스템에는 미디어 유형에 대한 다양한 견해가 있습니다. 일부는 애플리케이션 별 페이로드를 선호하는 반면, 다른 일부는 기존 미디어 유형을 애플리케이션에 적합한 역할로 끌어 올리는 것을 선호합니다. 예를 들어, 한편으로는 마이크로 포맷 및 기타 메커니즘을 통해 XHTML과 같은 것을 표현으로 사용하는 대신 애플리케이션에 맞게 설계된 특정 XML 스키마가 있습니다.

두 가지 접근 방식 모두 XHTML이 인간 중심 웹과 기계 중심 웹 모두 겹치는 시나리오에서 매우 잘 작동한다고 생각하는 반면, 전자의보다 구체적인 데이터 유형은 기계 간 상호 작용을 더 용이하게합니다. 상품 형식의 향상은 콘텐츠 협상을 잠재적으로 어렵게 만들 수 있습니다. "application / xml + yourresource"는 "application / xhtml + xml"보다 미디어 유형으로 훨씬 더 구체적입니다. 후자는 머신 클라이언트가 실제로 관심을 가질 수도 있고 그렇지 않을 수도있는 많은 페이로드에 적용 할 수 있기 때문입니다. 자기 성찰없이 결정합니다.

그러나 XHTML은 웹 브라우저와 렌더링이 매우 중요한 휴먼 웹에서 매우 잘 작동합니다 (분명히).

당신의 응용 프로그램은 이러한 종류의 결정에 당신을 안내 할 것입니다.

REST 시스템 설계 프로세스의 일부는 기본 리소스에 대한 작업을 지원하는 데 필요한 파생 지원 리소스와 함께 시스템에서 일급 리소스를 검색하는 것입니다. 리소스가 발견되면 해당 리소스의 표현뿐만 아니라 다음 도전으로 인해 표현 내에서 하이퍼 텍스트를 통한 리소스 흐름을 보여주는 상태 다이어그램이 표시됩니다.

하이퍼 텍스트 시스템에서 리소스의 각 표현은 리소스에 사용할 수있는 상태 전환과 함께 실제 리소스 표현을 결합합니다. 각 리소스를 그래프의 노드로 간주하고 링크는 해당 노드를 다른 상태로 떠나는 선입니다. 이러한 링크는 클라이언트에게 수행 할 수있는 작업뿐만 아니라 수행하는 데 필요한 사항을 알려줍니다 (좋은 링크는 필요한 URI와 미디어 유형을 결합하므로).

예를 들어 다음이있을 수 있습니다.

<link href="http://example.com/users" rel="users" type="application/xml+usercollection"/>
<link href="http://example.com/users?search" rel="search" type="application/xml+usersearchcriteria"/>

문서는 "users"라는 rel 필드와 "application / xml + youruser"의 미디어 유형에 대해 설명합니다.

이러한 링크는 중복 된 것처럼 보일 수 있으며 거의 ​​모두 동일한 URI를 사용하고 있습니다. 하지만 그렇지 않습니다.

이는 "users"관계의 경우 해당 링크가 사용자 컬렉션에 대해 말하고 있으며, 균일 한 인터페이스를 사용하여 컬렉션 작업을 수행 할 수 있기 때문입니다 (모두 검색하려면 GET, 모두 삭제하려면 DELETE 등).

이 URL에 게시하는 경우 "application / xml + usercollection"문서를 전달해야합니다.이 문서에는 문서 내에 단일 사용자 인스턴스 만 포함되어 있으므로 사용자를 추가 할 수 있습니다. 한번. 아마도 문서에서 컬렉션 대신 단일 사용자 유형을 전달할 수 있다고 제안 할 것입니다.

"검색"링크와 미디어 유형에 정의 된대로 검색을 수행하기 위해 애플리케이션에 필요한 것이 무엇인지 확인할 수 있습니다. 검색 미디어 유형에 대한 문서는 이것이 어떻게 작동하는지, 그리고 결과로 무엇을 기대하는지 알려줍니다.

그러나 여기서 요점은 URI 자체가 기본적으로 중요하지 않다는 것입니다. 애플리케이션은 클라이언트가 아니라 URI를 제어합니다. 몇 가지 '진입 지점'을 넘어 클라이언트는 작업을 위해 애플리케이션에서 제공하는 URI에 의존해야합니다.

클라이언트는 미디어 유형을 조작하고 해석하는 방법을 알아야하지만 어디로 가는지 신경 쓰지 않아도됩니다.

이 두 링크는 ​​클라이언트 눈에서 의미 상 동일합니다.

<link href="http://example.com/users?search" rel="search" type="application/xml+usersearchcriteria"/>
<link href="http://example.com/AW163FH87SGV" rel="search" type="application/xml+usersearchcriteria"/>

따라서 리소스에 집중하십시오. 응용 프로그램의 상태 전환과이를 가장 잘 달성하는 방법에 중점을 둡니다.


re 1 : 지금까지는 괜찮아 보입니다. POST에 대한 응답의 일부로 "201 Created"상태 코드와 함께 "Location :"헤더에 새로 생성 된 사용자의 URI를 반환해야합니다.

다시 2: GET을 통한 활성화는 나쁜 생각이며 URI에 동사를 포함하는 것은 디자인 냄새입니다. GET에서 양식 리턴을 고려할 수 있습니다. 웹 앱에서 이것은 제출 버튼이있는 HTML 양식입니다. API 사용 사례에서 계정을 활성화하기 위해 PUT에 대한 URI가 포함 된 표현을 반환 할 수 있습니다. 물론 / users에 대한 POST의 응답에도이 URI를 포함 할 수 있습니다. PUT를 사용하면 요청이 멱 등성을 보장합니다. 즉, 클라이언트가 성공 여부를 확신하지 못하는 경우 안전하게 다시 보낼 수 있습니다. 일반적으로, 동사를 어떤 자원으로 바꿀 수 있는지 생각해보십시오 (일종의 "동사의 명사"). 특정 작업이 가장 밀접하게 일치하는 방법이 무엇인지 자문 해보십시오. 예 : change_password-> PUT; 비활성화-> 아마도 DELETE; add_credit-> POST 또는 PUT 가능.

re 3. 새로운 상태 코드를 만들지 마십시오. 너무 일반적이라고 생각하지 않는 한 전 세계적으로 표준화 할 가치가 있습니다. 사용 가능한 가장 적절한 상태 코드를 사용하도록 노력하십시오 (RFC 2616에서 모두에 대해 읽어보십시오). 응답 본문에 추가 정보를 포함하십시오. 정말로 새로운 상태 코드를 만들고 싶다고 확신한다면 다시 생각해보십시오. 그래도 그렇게 생각한다면 적어도 올바른 범주를 선택하십시오 (1xx-> 확인, 2xx-> 정보, 3xx-> 리디렉션, 4xx-> 클라이언트 오류, 5xx-> 서버 오류). 새로운 상태 코드를 만드는 것이 나쁜 생각이라고 언급 했습니까?

re 4. 가능하다면 HTTP에 내장 된 인증 프레임 워크를 사용하십시오. Google이 GData에서 인증하는 방식을 확인하세요. 일반적으로 URI에 API 키를 넣지 마십시오. 확장 성을 높이고 캐싱을 지원하기 위해 세션을 피하십시오. 이전에 발생한 일로 인해 요청에 대한 응답이 다른 경우 일반적으로 특정 서버 프로세스 인스턴스에 자신을 연결 한 것입니다. 세션 상태를 클라이언트 상태로 바꾸거나 (예 : 후속 요청의 일부로) 세션 상태를 (서버) 리소스 상태로 바꿔 명시 적으로 만드는 것이 훨씬 낫습니다. 즉, 자체 URI를 제공합니다.


1. 당신은 당신의 자원, IMHO를 디자인하는 방법에 대한 올바른 아이디어를 가지고 있습니다. 나는 아무것도 바꾸지 않을 것입니다.

2. 더 많은 동사를 사용하여 HTTP를 확장하는 대신 기본 HTTP 메서드 및 리소스 측면에서 제안 된 동사를 줄일 수있는 방법을 고려합니다. 예를 들어 activate_login동사 대신 /api/users/1/login/active간단한 부울 인 다음과 같은 리소스를 설정할 수 있습니다 . 로그인을 활성화하려면 PUT'true'또는 1 등의 문서 만 있으면됩니다. 비활성화하려면 PUT비어 있거나 0 또는 거짓으로 표시된 문서입니다.

마찬가지로 암호를 변경하거나 설정하려면 PUTs를 /api/users/1/password.

크레딧과 같은 무언가를 추가해야 할 때마다 POSTs로 생각하십시오 . 예를 들어, 추가 할 크레딧 수를 포함하는 본문 POST과 같은 리소스에 a 수행 할 수 /api/users/1/credits있습니다. PUT동일한 리소스에있는 A 를 사용하여 값을 추가하는 대신 덮어 쓸 수 있습니다. POST본문에 음수가있는 A 는 빼는 식입니다.

3. 기본 HTTP 상태 코드를 확장하지 않는 것이 좋습니다. 상황과 정확히 일치하는 항목을 찾을 수없는 경우 가장 가까운 항목을 선택하고 응답 본문에 오류 세부 정보를 입력하세요. 또한 HTTP 헤더는 확장 가능합니다. 응용 프로그램은 원하는 모든 사용자 지정 헤더를 정의 할 수 있습니다. 예를 들어 내가 작업 한 애플리케이션 중 하나 404 Not Found는 여러 상황에서를 반환 할 수 있습니다. 이유 때문에 클라이언트가 응답 본문을 구문 분석하도록하는 대신 X-Status-Extended독점 상태 코드 확장이 포함 된 새 헤더를 추가했습니다 . 따라서 다음과 같은 응답을 볼 수 있습니다.

HTTP/1.1 404 Not Found    
X-Status-Extended: 404.3 More Specific Error Here

이렇게하면 웹 브라우저와 같은 HTTP 클라이언트가 일반 404 코드로 무엇을해야하는지 알 수 있으며 더 정교한 HTTP 클라이언트는 X-Status-Extended더 구체적인 정보를 위해 헤더 를 볼 수 있습니다 .

4. 인증을 위해 가능한 경우 HTTP 인증을 사용하는 것이 좋습니다. 그러나 IMHO는 쿠키 기반 인증을 사용하는 것이 더 쉽다면 아무런 문제가 없습니다.


REST 기초

REST에는 REST 클라이언트가 실제 REST 서비스의 애플리케이션 별 세부 정보 대신 표준에 의존해야한다는 균일 한 인터페이스 제약 조건이 있으므로 REST 클라이언트는 사소한 변경으로 인해 중단되지 않으며 재사용이 가능할 것입니다.

따라서 REST 클라이언트와 REST 서비스간에 계약이 있습니다. HTTP를 기본 프로토콜로 사용하는 경우 다음 표준이 계약의 일부입니다.

  • HTTP 1.1
    • 방법 정의
    • 상태 코드 정의
    • 캐시 제어 헤더
    • 수락 및 콘텐츠 유형 헤더
    • 인증 헤더
  • IRI (utf8 URI )
  • 본문 (하나 선택)
    • 등록 된 애플리케이션 특정 MIME 유형 (예 : maze + xml)
    • 공급 업체별 MIME 유형 (예 : vnd.github + json)
    • 일반 MIME 유형
      • 애플리케이션 별 RDF 어휘 (예 : ld + json & hydra , schema.org)
      • 응용 프로그램 특정 프로필, 예 : hal + json & 프로필 링크 매개 변수 (나는 추측한다)
  • 하이퍼 링크
    • 포함해야 할 항목 (하나 선택)
      • 링크 헤더로 보내기
      • 하이퍼 미디어 응답 (예 : html, atom + xml, hal + json, ld + json & hydra 등)으로 보내기
    • 의미론
      • IANA 링크 관계 및 사용자 지정 링크 관계 사용
      • 애플리케이션 별 RDF 어휘 사용

REST에는 REST 서비스와 클라이언트 간의 통신이 상태 비 저장이어야 함을 선언하는 상태 비 저장 제약 조건이 있습니다. 이는 REST 서비스가 클라이언트 상태를 유지할 수 없으므로 서버 측 세션 저장소를 가질 수 없음을 의미합니다. 모든 단일 요청을 인증해야합니다. 예를 들어 HTTP 기본 인증 (HTTP 표준의 일부)은 모든 요청과 함께 사용자 이름과 비밀번호를 전송하기 때문에 괜찮습니다.

질문에 답하기 위해

  1. 예, 가능합니다.

    클라이언트는 링크 관계 또는 링크 된 데이터 (RDF) 속성이있는 링크를 따르기 때문에 IRI 구조에 관심이없고 의미론에 관심이 있습니다.

    IRI에 대해 중요한 것은 단일 IRI가 단일 리소스 만 식별해야한다는 것입니다. 사용자와 같은 단일 리소스가 여러 다른 IRI를 가질 수 있습니다.

    좋은 IRI를 사용하는 이유는 매우 간단합니다 /users/123/password. IRI를 읽는 것만으로 이해하면 서버에 라우팅 로직을 작성하는 것이 훨씬 쉽습니다.

  2. PUT, PATCH, OPTIONS 등과 같은 더 많은 동사가 있지만 더 이상 필요하지 않습니다. 새 동사를 추가하는 대신 새 리소스를 추가하는 방법을 배워야합니다.

    activate_login -> PUT /login/active true deactivate_login -> PUT /login/active false change_password -> PUT /user/xy/password "newpass" add_credit -> POST /credit/raise {details: {}}

    (상태 비 저장 제약으로 인해 REST 관점에서는 로그인이 의미가 없습니다.)

  3. 사용자는 문제가 존재하는 이유에 대해 신경 쓰지 않습니다. 그들은 성공 또는 오류가 있는지, 그리고 아마도 이해할 수있는 오류 메시지 (예 : "죄송하지만 게시물을 저장할 수 없습니다."등)를 알고 싶어합니다.

    The HTTP status headers are your standard headers. Everything else should be in the body I think. A single header is not enough to describe for example detailed multilingual error messages.

  4. The stateless constraint (along with the cache and layered system constraints) ensures that the service scales well. You surely don't wan't to maintain millions of sessions on the server, when you can do the same on the clients...

    The 3rd party client gets an access token if the user grants access to it using the main client. After that the 3rd party client sends the access token with every request. There are more complicated solutions, for example you can sign every single request, etc. For further details check the OAuth manual.

Related literature


For the examples you stated I'd use the following:

activate_login

POST /users/1/activation

deactivate_login

DELETE /users/1/activation

change_password

PUT /passwords (this assumes the user is authenticated)

add_credit

POST /credits (this assumes the user is authenticated)

For errors you'd return the error in the body in the format that you got the request in, so if you receive:

DELETE /users/1.xml

You'd send the response back in XML, the same would be true for JSON etc...

For authentication you should use http authentication.


  1. Use post when you don't know how the new resource URI would look like (you create new user, application would assign the new user it's id), PUT for updating or creating resources that you know how are they going to be represented (example: PUT /myfiles/thisismynewfile.txt)
  2. return the error description in message body
  3. You can use HTTP authentication (if it's enough) Web services should be stateles

I would suggest (as a first pass) that PUT should only be used for updating existing entities. POST should be used for creating new ones. i.e.

/api/users     when called with PUT, creates user record

doesn't feel right to me. The rest of your first section (re. verb usage) looks logical, however.


Verbose, but copied from the HTTP 1.1 method specification at http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

9.3 GET

The GET method means retrieve whatever information (in the form of an entity) is identified by the Request-URI. If the Request-URI refers to a data-producing process, it is the produced data which shall be returned as the entity in the response and not the source text of the process, unless that text happens to be the output of the process.

The semantics of the GET method change to a "conditional GET" if the request message includes an If-Modified-Since, If-Unmodified-Since, If-Match, If-None-Match, or If-Range header field. A conditional GET method requests that the entity be transferred only under the circumstances described by the conditional header field(s). The conditional GET method is intended to reduce unnecessary network usage by allowing cached entities to be refreshed without requiring multiple requests or transferring data already held by the client.

The semantics of the GET method change to a "partial GET" if the request message includes a Range header field. A partial GET requests that only part of the entity be transferred, as described in section 14.35. The partial GET method is intended to reduce unnecessary network usage by allowing partially-retrieved entities to be completed without transferring data already held by the client.

The response to a GET request is cacheable if and only if it meets the requirements for HTTP caching described in section 13.

See section 15.1.3 for security considerations when used for forms.

9.5 POST

The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line. POST is designed to allow a uniform method to cover the following functions:

  - Annotation of existing resources;
  - Posting a message to a bulletin board, newsgroup, mailing list,
    or similar group of articles;
  - Providing a block of data, such as the result of submitting a
    form, to a data-handling process;
  - Extending a database through an append operation.

The actual function performed by the POST method is determined by the server and is usually dependent on the Request-URI. The posted entity is subordinate to that URI in the same way that a file is subordinate to a directory containing it, a news article is subordinate to a newsgroup to which it is posted, or a record is subordinate to a database.

The action performed by the POST method might not result in a resource that can be identified by a URI. In this case, either 200 (OK) or 204 (No Content) is the appropriate response status, depending on whether or not the response includes an entity that describes the result.

If a resource has been created on the origin server, the response SHOULD be 201 (Created) and contain an entity which describes the status of the request and refers to the new resource, and a Location header (see section 14.30).

Responses to this method are not cacheable, unless the response includes appropriate Cache-Control or Expires header fields. However, the 303 (See Other) response can be used to direct the user agent to retrieve a cacheable resource.

POST requests MUST obey the message transmission requirements set out in section 8.2.

See section 15.1.3 for security considerations.

9.6 PUT

The PUT method requests that the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server. If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI. If a new resource is created, the origin server MUST inform the user agent via the 201 (Created) response. If an existing resource is modified, either the 200 (OK) or 204 (No Content) response codes SHOULD be sent to indicate successful completion of the request. If the resource could not be created or modified with the Request-URI, an appropriate error response SHOULD be given that reflects the nature of the problem. The recipient of the entity MUST NOT ignore any Content-* (e.g. Content-Range) headers that it does not understand or implement and MUST return a 501 (Not Implemented) response in such cases.

If the request passes through a cache and the Request-URI identifies one or more currently cached entities, those entries SHOULD be treated as stale. Responses to this method are not cacheable.

The fundamental difference between the POST and PUT requests is reflected in the different meaning of the Request-URI. The URI in a POST request identifies the resource that will handle the enclosed entity. That resource might be a data-accepting process, a gateway to some other protocol, or a separate entity that accepts annotations. In contrast, the URI in a PUT request identifies the entity enclosed with the request -- the user agent knows what URI is intended and the server MUST NOT attempt to apply the request to some other resource. If the server desires that the request be applied to a different URI,

it MUST send a 301 (Moved Permanently) response; the user agent MAY then make its own decision regarding whether or not to redirect the request.

A single resource MAY be identified by many different URIs. For example, an article might have a URI for identifying "the current version" which is separate from the URI identifying each particular version. In this case, a PUT request on a general URI might result in several other URIs being defined by the origin server.

HTTP/1.1 does not define how a PUT method affects the state of an origin server.

PUT requests MUST obey the message transmission requirements set out in section 8.2.

Unless otherwise specified for a particular entity-header, the entity-headers in the PUT request SHOULD be applied to the resource created or modified by the PUT.

9.7 DELETE

The DELETE method requests that the origin server delete the resource identified by the Request-URI. This method MAY be overridden by human intervention (or other means) on the origin server. The client cannot be guaranteed that the operation has been carried out, even if the status code returned from the origin server indicates that the action has been completed successfully. However, the server SHOULD NOT indicate success unless, at the time the response is given, it intends to delete the resource or move it to an inaccessible location.

A successful response SHOULD be 200 (OK) if the response includes an entity describing the status, 202 (Accepted) if the action has not yet been enacted, or 204 (No Content) if the action has been enacted but the response does not include an entity.

If the request passes through a cache and the Request-URI identifies one or more currently cached entities, those entries SHOULD be treated as stale. Responses to this method are not cacheable.


About REST return codes: it is wrong to mix HTTP protocol codes and REST results.

However, I saw many implementations mixing them, and many developers may not agree with me.

HTTP return codes are related to the HTTP Request itself. A REST call is done using a Hypertext Transfer Protocol request and it works at a lower level than invoked REST method itself. REST is a concept/approach, and its output is a business/logical result, while HTTP result code is a transport one.

For example, returning "404 Not found" when you call /users/ is confuse, because it may mean:

  • URI is wrong (HTTP)
  • No users are found (REST)

"403 Forbidden/Access Denied" may mean:

  • Special permission needed. Browsers can handle it by asking the user/password. (HTTP)
  • Wrong access permissions configured on the server. (HTTP)
  • You need to be authenticated (REST)

And the list may continue with '500 Server error" (an Apache/Nginx HTTP thrown error or a business constraint error in REST) or other HTTP errors etc...

From the code, it's hard to understand what was the failure reason, a HTTP (transport) failure or a REST (logical) failure.

If the HTTP request physically was performed successfully it should always return 200 code, regardless is the record(s) found or not. Because URI resource is found and was handled by the http server. Yes, it may return an empty set. Is it possible to receive an empty web-page with 200 as http result, right?

Instead of this you may return 200 HTTP code and simply a JSON with an empty array/object, or to use a bool result/success flag to inform about the performed operation status.

Also, some internet providers may intercept your requests and return you a 404 http code. This does not means that your data are not found, but it's something wrong at transport level.

From Wiki:

In July 2004, the UK telecom provider BT Group deployed the Cleanfeed content blocking system, which returns a 404 error to any request for content identified as potentially illegal by the Internet Watch Foundation. Other ISPs return a HTTP 403 "forbidden" error in the same circumstances. The practice of employing fake 404 errors as a means to conceal censorship has also been reported in Thailand and Tunisia. In Tunisia, where censorship was severe before the 2011 revolution, people became aware of the nature of the fake 404 errors and created an imaginary character named "Ammar 404" who represents "the invisible censor".

참고URL : https://stackoverflow.com/questions/2001773/understanding-rest-verbs-error-codes-and-authentication

반응형