REST API-PUT DELETE POST GET을 사용하는 이유는 무엇입니까?


155

그래서 REST API 작성에 대한 기사를 살펴 보았습니다. 그리고 그들 중 일부는 모든 유형의 HTTP 요청을 사용하도록 제안합니다 PUT DELETE POST GET. 예를 들어 index.php를 만들고 API를 다음과 같이 작성합니다.

$method = $_SERVER['REQUEST_METHOD'];
$request = split("/", substr(@$_SERVER['PATH_INFO'], 1));

switch ($method) {
  case 'PUT':
    ....some put action.... 
    break;
  case 'POST':
    ....some post action.... 
    break;
  case 'GET':
    ....some get action.... 
    break;
  case 'DELETE':
    ....some delete action.... 
    break;
}

물론, 웹 서비스에 대해 잘 모르고 있습니다 (아직). 그러나 일반 또는 메소드 이름과 모든 매개 변수를 포함하는 JSON 객체를 수락 한 다음 JSON으로 응답 하는 것이 쉽지 않을 것 입니다. 우리는 쉽게 직렬화 / 역 직렬화 PHP의를 통해 수 및 다른 HTTP 요청 방법으로 처리 할 필요없이 우리가 그 데이터를 원하는대로 할.POSTGETjson_encode()json_decode()

뭔가 빠졌습니까?

업데이트 1 :

Ok-다양한 API를 파고 XML-RPC , JSON-RPC , SOAP , REST 에 대해 많이 배운 후이 유형의 API가 적합하다는 결론에 도달했습니다. 실제로 스택 교환은 사이트에서이 접근 방식을 거의 사용하고 있으며 이러한 사람들은 Stack Exchange API를 수행하는 작업을 알고 있다고 생각합니다 .


4
왜 JSON 페이로드를 강제해야합니까? JSON이없고 평범한 오래된 GET이라면 ​​어떻게 되나요?
Mike DeSimone

답변:


200

의 아이디어 RE 표상 S 탓에 T 를 ransfer하지 않음을 가능한 한 가장 간단한 방법으로 데이터를 액세스하는 방법에 대한.

게시 요청을 사용하여 JSON에 액세스 할 것을 제안했는데 이는 데이터에 액세스 / 조작하는 데 가장 효과적인 방법입니다.

REST는 의미있는 데이터 액세스를 위한 방법입니다 . REST에서 요청이 표시되면 데이터에서 발생하는 상황에 즉시 대응해야합니다.

예를 들면 다음과 같습니다.

GET: /cars/make/chevrolet

시보레 자동차 목록을 반환 할 가능성이 높습니다. 좋은 REST API는 쿼리 문자열에 일부 출력 옵션을 통합 ?output=json하거나 ?output=html접근자가 정보를 인코딩해야하는 형식을 결정할 수 있도록합니다.

어떻게 REST API를에 합리적 법인 (法人) 데이터 유형에 대한 생각을 조금 후에, 나는 가장 좋은 방법은 같은 이미 존재하는 파일 확장자를 통해 것 명시 적으로 데이터의 유형을 지정하는 것으로 결론을했습니다 .js, .json, .html, 또는 .xml. 누락 된 파일 확장자는 기본적으로 모든 형식 (예 : JSON)으로 설정됩니다. 지원되지 않는 파일 확장자는 501 Not Implemented상태 코드를 반환 할 수 있습니다 .

다른 예시:

POST: /cars/
{ make:chevrolet, model:malibu, colors:[red, green, blue, grey] }

관련 색상으로 db에 새로운 시보레 말리부를 만들 것입니다. 내가 말할 가능성이 나머지 API를 직접 데이터베이스 구조와 관련 될 필요가 없기 때문에. 실제 데이터가 보호되도록 마스킹 인터페이스 일뿐입니다 (데이터베이스 구조에 대한 접근 자 및 변경자와 같은 것으로 생각하십시오).

이제 우리는 dem 등분 문제로 넘어 가야 합니다. 일반적으로 REST는 CRUD over HTTP를 구현 합니다. HTTP를 사용 GET, PUT, POSTDELETE요청합니다.

매우 간단한 REST 구현은 다음 CRUD 맵핑을 사용할 있습니다.

Create -> Post
Read   -> Get
Update -> Put
Delete -> Delete

이 구현에는 문제가 있습니다. Post는 비등 전성 메서드로 정의됩니다. 이는 동일한 Post 메소드의 후속 호출은 다른 서버 상태를 초래 함을 의미합니다 . Get, Put 및 Delete는 dem 등원입니다. 즉, 여러 번 호출하면 동일한 서버 상태가됩니다.

이는 다음과 같은 요청을 의미합니다.

Delete: /cars/oldest

실제로 다음과 같이 구현할 수 있습니다.

Post: /cars/oldest?action=delete

이므로

Delete: /cars/id/123456

한 번 호출하거나 1000 번 호출하면 동일한 서버 상태가됩니다.

oldest품목 제거를 처리하는 더 좋은 방법 은 다음을 요청하는 것입니다.

Get: /cars/oldest

그리고 ID결과 데이터를 사용하여 delete요청하십시오.

Delete: /cars/id/[oldest id]

이 방법의 문제 는 요청 시점과 발행 시점 /cars사이에 다른 항목이 추가 된 경우입니다./oldestdelete


3
@Andre는 여러 가지 이유의 조합입니다. HTTP 지침을 따르면 상황이 변경 될 때 이전 버전과의 호환성 문제가 줄어들 것입니다. POST를 통해 html 양식을 사용하면 사용자에게 동일한 데이터를 여러 번 제출할 것을 경고합니다 (비등 전 거래를 방지하기 위함). 잘 정의 된 모범 사례를 따르는 것이 좋습니다. 나머지는 특정 구현을 염두에두고 정의되어 있지 않으므로 원하는대로 사용할 수 있습니다. 모든 HTTP 오류 코드와 요청 메소드를 활용하는 것이 좋습니다. 그러나 원하는대로 수행 할 수 있습니다.
zzzzBov

4
따라서이 답변의 문제 (괜찮은 대답이지만 완전하지는 않음)는 그가 묻는 주요 질문을 해결하지 못한다는 것입니다. 왜 사용자 정의 JSON 데이터 대신 HTTP 동사와 URI를 사용합니까? JSON 기반 API 호출 구문). 사용자 정의 JSON 구문을 작성하여 "데이터에서 발생하는 상황을 즉시 ... 심각하게"할 수 있습니다. 할 수없는 것은 모든 REST 규칙을 따르는 API를 사용하는 것처럼 HTTP 위에 내장 기능과 네트워크 계층을 쉽게 사용하는 것입니다. 물론 내 대답은 완벽하지는 않습니다.)
Merlyn Morgan-Graham

4
@Andre : 위키 항목이 사용하는 예는 인증, 캐싱 및 컨텐츠 유형 협상입니다. 이제 그것에 대해 더 많이 생각하고 있으므로 RPC 스타일 인터페이스와 함께 사용할 수는 있지만 자신의 시스템을 처음부터 구현하거나 기존 시스템에 통합을 코딩하는 유혹이 종종 있습니다. REST를 사용하면 내장 통합을 사용하고 웹 서버에서 관리 할 수 ​​있습니다. 즉, 커플 링이 느슨해 짐에 따라 구현이 적어야하며, 코드가 적고 테스트 영향이 적을수록 앱이 옵션을 변경하기가 훨씬 유연 해집니다.
Merlyn Morgan-Graham

10
DELETE : / cars / oldest 대신 GET : / cars / oldest와 DELETE는 어떻습니까? 이런 식으로, 당신은 두 개의 분리 된 dem 등원 명령을 가지고 있습니다.
Neil

3
+1; 나는 이것이 좋은 대답이라고 동의합니다 (재미와 이익을 위해 다시 거듭 나고 있습니다). POST: /cars/oldestDELETE를 대체하는 것은 의미가 없습니다. 같은 뭔가 - POST: /cars/oldest/delete힘은, 그래도 나는 닐의 솔루션보다처럼 생각합니다. 직접 삭제가 get-id-delete-id 솔루션에 비해 제공하는 유일한 장점은 원 자성입니다. 그러한 일을 구현하기 전에 논란의 여지가없는 시나리오로 명확한 비즈니스 타당성을 원합니다. 모든 객체 / URL에서 모든 동사를 지원할 필요는 없습니다.
Merlyn Morgan-Graham

39

이것은 보안 및 유지 관리 성 질문입니다.

안전한 방법

가능할 때마다 잠재적 취약성을 제한하기 위해 GET 및 HEAD와 같은 '안전한'(단방향) 방법을 사용해야합니다.

dem 등식 방법

가능하면 GET, HEAD, PUT 및 DELETE와 같은 '등전위 (idempotent)'방법을 사용해야합니다.이 방법은 부작용이 없으므로 제어하기 쉬운 오류가 적습니다.

출처


1
죄송하지만 PUT 및 DELETE는 dem 등원 방법은 어떻습니까? 서버 상태와 데이터에 영향을줍니다!
Mahmoud Al-Qudsi

27
@ 컴퓨터 : 동일한 PUT 또는 동일한 삭제를 수행하면 동일한 최종 상태가됩니다. 그것이 "등전위"의 의미입니다.
Ignacio Vazquez-Abrams

4
더 명확하게 설명하자면, 단일 애플리케이션과 여러 개의 후속 애플리케이션이 모두 동일한 결과를 리턴하는 경우 오퍼레이션 F는 dem 등원입니다. 더 정확하게 F는 F (x) = F (F (x)) 인 경우에만 dem 등원입니다. 예를 들어, 삭제는 dem 등원입니다. 항목을 한 번 삭제하거나 여러 번 삭제하면 결과는 동일합니다. 항목은 첫 번째 삭제 애플리케이션으로 한 번만 삭제되고 두 번째 또는 세 번째 삭제에서는 아무 것도 발생하지 않습니다.
qartal

1
그러나 작성과 관련하여 작성 명령으로 새 레코드를 작성하고 동일한 명령을 다시 발행하면 두 개의 레코드가 작성됩니다 (둘 다 동일한 정보를 반영하지만).
qartal

qartal-dem 등원에 대한 함수 정의는 'F (X) = F (X) F (X)'여야합니다. 그래도 좋은 방법입니다.
제라드 ONeill

26

요컨대 REST는 동사보다 명사를 강조합니다. API가 복잡 해짐에 따라 더 많은 명령이 아닌 더 많은 것을 추가합니다.


2
머리를 둥글게하는 데 약간의 어려움이있었습니다. 이 게시물이 ( lornajane.net/posts/2013/... URI가 만 명사를 포함해야합니다 있도록 동사는 HTTP 요청에서 오는되어야한다)는 나를 위해 조금 그것을 정리
icc97

9

당신은 물었다 :

정상적인 $ _POST를 통해 JSON 객체를 수락 한 다음 JSON에서도 응답하는 것이 쉽지 않을 것입니다

REST Wikipedia에서 :

RESTful 애플리케이션은 선택한 네트워크 프로토콜에서 제공하는 기존의 잘 정의 된 인터페이스 및 기타 내장 기능의 사용을 최대화하고 그 위에 새로운 애플리케이션 별 기능의 추가를 최소화합니다

내가 본 (작은) 것으로부터, 나는 이것이 일반적으로 기존 HTTP 동사의 사용을 최대화하고 가능한 강력하고 자명 한 서비스를 위해 URL 스킴을 설계함으로써 달성된다고 생각합니다.

사용자 정의 데이터 프로토콜 (SOAP 또는 JSON과 같은 표준 프로토콜 위에 구축 된 경우에도)은 권장되지 않으며 REST 이념에 가장 잘 맞게 최소화해야합니다.

반면에 SOAP RPC over HTTP는 각 응용 프로그램 디자이너가 명사와 동사 (예 : getUsers (), savePurchaseOrder (...))의 새롭고 임의적 인 어휘를 정의하도록 권장합니다. 일반적으로 HTTP 'POST'동사에 중첩됩니다. 이는 인증, 캐싱 및 컨텐츠 유형 협상과 같은 많은 HTTP의 기존 기능을 무시하고 애플리케이션 설계자가 새로운 기능 내에서 이러한 기능 중 많은 기능을 다시 발명하게 할 수 있습니다.

작업중인 실제 객체는 모든 형식 일 수 있습니다. 아이디어는 사용자가 해당 리소스에서 수행하려는 작업 (쿼리, 상태 관리 / 돌연변이, 삭제)을 노출하기 위해 가능한 한 많은 HTTP를 재사용하는 것입니다.

당신은 물었다 :

뭔가 빠졌습니까?

REST 및 URI 구문 / HTTP 동사 자체에 대해 더 많은 정보가 있습니다. 예를 들어, 동사 중 일부는 dem 등원이고 다른 동사는 그렇지 않습니다. 나는 당신의 질문에서 이것에 대해 아무것도 보지 못했기 때문에 그것에 들어 가려고 노력하지 않았습니다. 다른 답변과 Wikipedia에는 ​​좋은 정보가 많이 있습니다.

또한 진정으로 편안한 API를 사용하는 경우 활용할 수있는 HTTP를 기반으로 구축 된 다양한 네트워크 기술에 대해 배울 것이 많습니다. 인증부터 시작하겠습니다.


8

확장을 사용하여 데이터 유형을 정의하는 것과 관련하여. MailChimp API 가하고 있음을 알았지 만 이것이 좋은 생각은 아닙니다.

GET /zzz/cars.json/1

GET /zzz/cars.xml/1

좋은 생각처럼 들리지만 HTTP 헤더를 사용하면 "오래된"접근 방식이 더 좋습니다.

GET /xxx/cars/1
Accept: application/json

또한 HTTP 헤더는 교차 데이터 유형 통신에 훨씬 좋습니다 (누군가 필요할 경우)

POST /zzz/cars
Content-Type: application/xml     <--- indicates we sent XML to server
Accept: application/json          <--- indicates we want get data back in JSON format  

4

뭔가 빠졌습니까?

예. ;-)

이 현상은 균일 한 인터페이스 제약 때문에 존재합니다 . REST는 휠을 재창조하는 대신 기존 표준을 사용하는 것을 좋아합니다. HTTP 표준은 이미 확장 성이 뛰어난 것으로 입증되었습니다 (웹은 한동안 작동합니다). 왜 깨지지 않은 것을 고쳐야합니까?!

참고 : 클라이언트를 서비스에서 분리하려면 균일 한 인터페이스 제약 조건이 중요합니다. 클래스를 서로 분리하기 위해 클래스에 대한 인터페이스를 정의하는 것과 유사합니다. Ofc. 여기에 균일 한 인터페이스는 같은 표준으로 구성 HTTP , MIME 타입 , URI , RDF , 링크 된 데이터 Vocabs에 , 히드라의 Vocab의 등 ...


2

좋은 의미론은 프로그래밍에서 중요합니다.

GET / POST 외에 더 많은 방법을 사용하면 코드의 가독성이 향상되고 유지 관리가 쉬워 지므로 도움이됩니다.

왜?

GET이 API에서 데이터를 검색한다는 것을 알고 있기 때문입니다. POST가 시스템에 새 데이터를 추가한다는 것을 알고 있습니다. PUT이 업데이트 할 것임을 알고 있습니다. DELETE는 행 등을 삭제합니다.

나는 보통 RESTFUL 웹 서비스를 구성하여 메소드와 같은 이름의 함수 콜백을 갖습니다.

나는 PHP를 사용하므로 function_exists를 사용한다. 함수가 존재하지 않으면 405 (METHOD NOT ALLOWED)를 던집니다.


2

Bill Venners : "Why REST 실패"라는 제목의 블로그 게시물에서 GET, POST, PUT 및 DELETE라는 4 개의 HTTP 동사가 모두 필요하다고 말하고 브라우저 공급 업체에만 GET 및 POST 만 애도 한 이유는 무엇입니까? " 왜 GET과 POST가 충분하지 않습니까?

Elliotte Rusty Harold : HTTP에는 GET, POST, PUT 및 DELETE의 네 가지 기본 방법이 있습니다. GET이 대부분 사용됩니다. 그것은 안전하고 부작용을 일으키지 않는 모든 것에 사용됩니다. GET은 북마크, 캐시, 링크, 프록시 서버를 통해 전달 될 수 있습니다. 매우 강력한 작업이며 매우 유용한 작업입니다.

대조적으로 POST는 아마도 가장 강력한 작업 일 것입니다. 그것은 무엇이든 할 수 있습니다. 발생할 수있는 일에 대한 제한이 없으므로 결과적으로 매우주의해야합니다. 북마크하지 않습니다. 캐시하지 않습니다. 미리 가져 오지 않습니다. 사용자에게 묻지 않고 POST로 아무 작업도 수행하지 않습니다. 이 작업을 원하십니까? 사용자가 버튼을 누르면 일부 내용을 게시 할 수 있습니다. 그러나 페이지의 모든 버튼을보고 무작위로 누르는 것은 아닙니다. 대조적으로 브라우저는 페이지의 모든 링크를보고 미리 가져 오거나 다음에 가장 가능성이 높다고 생각되는 링크를 미리 가져옵니다. 실제로 일부 브라우저와 Firefox 확장 프로그램 및 기타 다양한 도구가 한 지점에서 다른 작업을 시도했습니다.

PUT과 DELETE는 GET과 POST 사이의 중간에 있습니다. PUT 또는 DELETE와 POST의 차이점은 PUT과 DELETE가 * 등가 인 반면 POST는 그렇지 않다는 것입니다. 필요한 경우 PUT 및 DELETE를 반복 할 수 있습니다. 새 페이지를 사이트에 업로드하려고한다고 가정 해 봅시다. http://www.example.com/foo.html 에서 새 페이지를 만들고 싶다고 가정 해 봅시다 .콘텐츠를 입력하고 해당 URL에 콘텐츠를 넣습니다. 서버는 사용자가 제공 한 해당 URL에 해당 페이지를 작성합니다. 이제 어떤 이유로 네트워크 연결이 끊겼다 고 가정 해 봅시다. 확실하지 않습니다. 요청이 통과 되었습니까? 네트워크 속도가 느릴 수 있습니다. 프록시 서버 문제 일 수 있습니다. 따라서 원하는만큼 여러 번 다시 시도해도됩니다. 같은 문서를 같은 URL에 10 번 퍼팅하는 것은 한 번 두는 것과 다를 바가 없습니다. DELETE도 마찬가지입니다. 무언가를 10 번 삭제할 수 있으며 한 번 삭제하는 것과 같습니다.

대조적으로 POST는 매번 다른 일이 발생할 수 있습니다. 구매 버튼을 눌러 온라인 상점을 체크 아웃한다고 가정합니다. POST 요청을 다시 보내면 카트의 모든 것을 다시 구매하게 될 수 있습니다. 다시 보내면 세 번째 구매 한 것입니다. 그렇기 때문에 POST는 명시적인 사용자 동의없이 POST 작업을 반복하는 데 매우주의해야합니다. POST는 두 번 수행하면 두 가지 일이 발생하고 세 번 수행하면 세 가지 일이 발생할 수 있기 때문입니다. PUT과 DELETE를 사용하면 요청 0과 1 사이에 큰 차이가 있지만 한 요청과 10 사이에는 차이가 없습니다.

자세한 내용은 URL을 방문하십시오. http://www.artima.com/lejava/articles/why_put_and_delete.html

최신 정보:

dem 등원 메소드 dem 등원 HTTP 메소드는 다른 결과없이 여러 번 호출 할 수있는 HTTP 메소드입니다. 메소드가 한 번만 또는 10 번 이상 호출되는지는 중요하지 않습니다. 결과는 같아야합니다. 다시 말하지만 이것은 리소스 자체가 아니라 결과에만 적용됩니다. 이 정보가 (현재) 리소스 표현에서 공유되지 않는 경우 여전히 업데이트 타임 스탬프와 같이 조작 할 수 있습니다.

다음 예를 고려하십시오.

a = 4;

a ++;

첫 번째 예제는 dem 등수입니다.이 문장을 몇 번이나 실행하더라도 a는 항상 4입니다. 두 번째 예제는 dem 등수가 아닙니다. 이 10 번 실행하면 5 번 실행했을 때와 다른 결과가 나타납니다. 두 예제 모두 a의 값을 변경하므로 두 가지 모두 안전하지 않은 방법입니다.


1
새 페이지의 예에 대해서는 POST 방식으로 POST를 사용하지 말고 PUT을 업데이트해야합니까? 새 페이지를 작성하는 것은 매번 새로운 결과를 작성하는 프로세스이며, 동일한 편집을 여러 번 반복하여 매번 동일한 결과를 생성 할 수 있습니다. 그래도 좋은 문구와 설명.
Spyryto

0

기본적으로 REST는 ( wiki )입니다.

  1. 클라이언트-서버 아키텍처
  2. 무국적
  3. 캐시 가능성
  4. 계층화 된 시스템
  5. 주문형 코드 (선택 사항)
  6. 균일 한 인터페이스

REST는 프로토콜이 아니라 원칙입니다. 다른 소변과 방법-누군가가 모범 사례라고합니다.

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