REST, HTTP 삭제 및 매개 변수


135

HTTP DELETE 요청에 매개 변수를 제공하는 것과 관련하여 신뢰할만한 것이 있습니까?


내 시나리오는 "정말 삭제 하시겠습니까?"를 모델링하는 것입니다. 대본. 경우에 따라 리소스 상태에 따라 요청 된 삭제가 유효하지 않을 수 있습니다. 삭제 확인이 필요한 시나리오를 직접 상상할 수 있습니다.

우리가 채택한 해결책은 삭제 요청에 매개 변수를 전달하여 삭제를 진행해도 괜찮음을 표시하는 것입니다 ( "? force_delete = true").

예 :

DELETE http://server/resource/id?force_delete=true

나는 그것이 이후로 여전히 편안하다고 믿습니다.

(a) DELETE의 의미는 변경되지 않습니다-사용자는 여전히 정상적인 DELETE 요청을 보낼 수 있지만 409에서 실패 할 수 있으며 응답 본문에서 이유를 설명합니다. 어떤 경우에는 사용자에게 프롬프트 할 이유가 없기 때문에 설명 할 가치가 없기 때문에 실패 할 수 있습니다.

(b) Roy의 논문에는 REST의 정신에 위배된다고 제안하는 것이 없습니다. HTTP가 REST의 한 가지 구현이기 때문에 HTTP 매개 변수를 전달하는 것이 중요한 이유는 무엇입니까?


누군가 이것이 왜 RESTful하지 않은 이유를 설명하는 명확한 진술을 알려 줄 수 있습니까?

관련 질문에 대해 사용자가 force_delete를 지정하지 않으면 반환됩니다 409 Conflict. 가장 적합한 응답 코드입니까?


후속 조치

좀 더 연구 한 후에 DELETE에 매개 변수를 추가하면 몇 가지 원칙을 위반 할 수 있다고 생각합니다.

첫 번째는 구현이 "유니폼 인터페이스"를 위반할 가능성이 있다는 것입니다 ( Roy 논문의 5.1.5 섹션 참조)

'force_delete'를 추가하여 이미 잘 정의 된 DELETE 메소드에 추가 제약 조건을 추가합니다. 이 제약은 우리에게만 의미가 있습니다.

확인 대화가 실제로 UI 문제이므로 모든 클라이언트가 삭제를 확인하지는 않기 때문에 "5.1.2 클라이언트-서버"를 위반한다고 주장 할 수도 있습니다.

누군가 제안?


1
Roy의 논문에 대한 귀하의 URL에 ")"가 포함되어있어 404가 발생 합니다. ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm이 작동합니다.
NuclearPeon

답변:


78

아니요, RESTful하지 않습니다. 동사 force_delete에 URI ( )를 넣어야하는 유일한 이유 는 PUT / DELETE 메소드를 사용할 수없는 환경에서 GET / POST 메소드를 과부하해야하는 경우입니다. DELETE 방법의 사용으로 판단하면 그렇지 않습니다.

409/ConflictRESTful 서비스가 조작을 수행하지 못하게하는 충돌이있는 상황에서는 HTTP 오류 코드를 사용해야하지만 사용자가 충돌을 스스로 해결할 수있는 가능성은 여전히 ​​있습니다. 삭제 요청을 방지하는 실제 충돌이없는 사전 삭제 확인은 그 자체가 충돌이 아닙니다. API가 요청 된 작업을 수행하는 것을 막는 것은 없습니다.

Alex가 말했듯이 (누가 그를 공감했는지 모르겠습니다. 그는 정확합니다), RESTful 서비스는 요청을 처리하기 때문에 상태가 없어야하기 때문에 UI에서 처리해야합니다. 요청에 대한 서버 측 정보).

UI에서이를 수행하는 두 가지 예는 다음과 같습니다.

  • pre-HTML5 : * 사용자에게 JS 확인 대화 상자를 표시하고 사용자가 확인한 경우에만 요청을 보냅니다.
  • HTML5 : * 양식에 "확인"및 "취소"버튼 만 포함 된 DELETE 조치가있는 양식을 사용하십시오 ( "확인"은 제출 버튼 임).

(*) 5 이전의 HTML 버전은 기본적으로 PUT 및 DELETE HTTP 메소드를 지원하지 않지만 대부분의 최신 브라우저는 AJAX 호출을 통해이 두 가지 메소드를 수행 할 수 있습니다. 브라우저 간 지원에 대한 자세한 내용은 이 스레드 를 참조하십시오 .


업데이트 (추가 조사 및 토론 기준) :

서비스가 force_delete=true플래그를 제시 해야하는 시나리오 는 Roy Fielding의 논문에 정의 된대로 균일 한 인터페이스 를 위반합니다 . 또한 HTTP RFC 에 따라 원본 서버 (클라이언트)에서 DELETE 메소드가 대체 될 수 있으며 이는 대상 서버 (서비스)에서 수행되지 않음을 의미합니다.

따라서 서비스가 DELETE 요청을 받으면 서비스가 실제로 작업을 수행하는지 여부에 관계없이 추가 확인없이 서비스를 처리해야합니다.


2
어떤 REST 제약 조건이 위반되는지 설명 할 수 있습니까? URI가 클라이언트에게 불투명해야한다는 것을 고려할 때, 한 자원을 삭제하지만 다른 자원을 삭제하지 못하는 HTTP DELETE의 사용으로 클라이언트의 기대가 충족되지 않는다고 생각하는 이유는 무엇입니까? 409가 반환하기에 가장 좋은 상태 코드인지 확실하지 않지만 약간 이상한 구현 외에도 깨진 REST 제약 조건을 찾을 수 없습니다.
Darrel Miller

2
@Darrel : (imho) HTTP 표준에 따라 수행되지 않는 DELETE 메소드에 의해 균일 한 인터페이스를 위반합니다. 표준 REST 서비스를 가정하는 REST 클라이언트를 고려하십시오. 서비스가 클라이언트에게 추가해야한다는 것을 어떻게 알 수 force_delete=true있습니까? HTTP RFC에 따라 DELETE 메소드는 원래 서버 (클라이언트)에서 대체 될 수 있으며 이는 대상 서버 (서비스)에서 수행되지 않음을 의미합니다. 따라서 서비스가 DELETE 요청을 받으면 서비스가 실제로 작업을 수행하는지 여부에 관계없이 확인이 필요없이 처리해야한다는 것을 이해합니다.
MicE

1
@Chris, 두 번째 요점 : 그렇습니다, 그것은 또한 저의 이해이기도합니다. 방금 질문에 수행 한 업데이트를 발견했으며 동의합니다. 내가 직접 조사하는 동안 동일한 결론에 도달했습니다 (이것은 균일 한 인터페이스를 위반하며 클라이언트 / UI에서 확인을 수행해야한다는 것입니다) 측면). : 나는 또한 그것은 도움이 될 수 있습니다, 여기에 매우 흥미로운 스레드를 가로 질러 mail-archive.com/pylons-discuss@googlegroups.com/msg13578.html
마우스

2
@MicE이 시나리오를 처리하는 이상적인 방법은 아니라는 점에 동의합니다. 나는 "휴식하지 않다"라는 라벨에 대해 약간 까다 롭다. 잠시 동안이 문구는 모든 것에 던져졌습니다. 그러나 자원을 삭제하려고 시도하고 오류가 발생하면 (403은 금지 된 것이 409보다 낫다고 말한 경우) 클라이언트가 관련 자원에 대해 DELETE를 시도해야한다는 매체 유형에 대한 규칙을 정의 할 수 있습니다. "force_delete = true"를 선택하면됩니다. 어떤면에서 그것은 승인과 조금 비슷합니다. GET을 수행하고 401을 얻고 인증 헤더를 추가 한 후 다시 GET하십시오.
Darrel Miller

2
@Darrel : 아주 좋은 지적입니다. 감사합니다. 그리고 사람들이 RESTful아닌 라벨을 직접 던지는 것을 보았습니다. 요즘 서비스와 웹 응용 프로그램 간의 장벽이 매우 어두워 져서 한 사람의 사람들이 순수한 서비스 관점에서이를 볼 수 있고 다른 사람들은 혼합 된 응용 프로그램 / 서비스 관점에서이를 볼 수 있습니다. 즉, 확인을 수행하는 방법에 대한 실제 질문이 어디에서 발생하는지 믿습니다. @Chris : 업데이트 됨-매우 흥미로운 주제와 토론에 대해 감사합니다!
MicE

35

나는 이것이 불안하지 않다고 생각합니다. 편안한 서비스는 사용자가 삭제를 확인하도록 요구하는 요구 사항을 처리해야한다고 생각하지 않습니다. 나는 이것을 UI에서 처리 할 것입니다.

이것이 프로그램의 API 인 경우 force_delete = true를 지정하는 것이 의미가 있습니까? 누군가이 자원을 삭제하기위한 스크립트를 작성하고 있다면, 실제로 자원을 삭제하도록 force_delete = true를 지정하도록 하시겠습니까?


귀하의 의견에 대한 첫 번째 단락은 귀하의 의견이며 본인은 존중하지만 귀하는 이와 같은 URI 사용을 금지하는 문헌을 지적하지 않았습니다. 여전히 리소스를 식별하고 가장 적합한 HTTP 동사가 사용되고 있습니다. 귀하의 질문에 대한 답변; 예, 여전히 이해가됩니다 (제 의견으로는). 내 모든 응답 본문에 따라 - 난 409 응답을 존중하고 요청 재전송을 수있는 방법을 사용자에게 제안 (아마도 CURL 기준) 스크립트를 기대
크리스 맥컬리

웹 API를 프로그램의 API와 비교하는 것이 좋습니다. API가 RESTful인지 아닌지를 알 수있는 좋은 방법입니다.
laurent

18

오래된 질문이지만 여기에 몇 가지 의견이 있습니다 ...

  1. SQL에서 DELETE 명령은 "CASCADE"매개 변수를 허용하며,이를 통해 종속 오브젝트도 삭제되도록 지정할 수 있습니다. 이것은 의미가있는 DELETE 매개 변수의 예이지만 'man rm'은 다른 것을 제공 할 수 있습니다. 이러한 경우를 매개 변수없이 REST / HTTP에서 어떻게 구현할 수 있습니까?
  2. @Jan, URL의 경로 부분이 리소스를 식별하는 반면, 쿼리 문자열은 반드시 그런 것은 아닙니다. 예 : 풍부함 : 동일한 리소스를 가져 오지만 다른 형식으로, 리소스의 특정 필드 가져 오기 등 HTTP 콘텐츠 협상과 같은 비 RESTT 메커니즘으로 전환하지 않고 여러 가지 이유로 바람직하지 않을 수 있습니다.

지난 몇 년 동안 대화가 많지 않더라도 대화에 추가해 주셔서 감사합니다.
silviot

6

Alex의 답변 외에도

참고 HTTP : // 서버 / 자원 / ID force_delete = 사실 보다는 식별 다른 자원 // 서버 / 자원 / ID : HTTP . 예를 들어 / customers /? status = old 또는 / customers /를 삭제하는지 여부는 크게 다릅니다.


동의하지 않습니다. 동일한 리소스를 식별하기 위해 여러 개의 URI를 자유롭게 제공 할 수 있습니다.
Chris McCauley

18
네-누구나 엉망으로 만들 수 있습니다 :-)
Jan Algermissen

표준 URI를 표시하면 다음과 같이 도움이 될 수 있습니다. googlewebmastercentral.blogspot.com/2009/02/…
MicE

@Chris 리소스의 표현을 반환하는 URI는 하나만 있어야합니다. 다른 URI는 동일한 개념을 참조 할 수 있지만 GET을 수행하면 303 See Other를 반환해야합니다. 그리고 이것에 대한 명백한 반대에 대응하기 위해 /foo.xml과 /foo.json은 서로 다른 두 가지 자원입니다.
Darrel Miller

@Darrell-동의하지만 형식은 문제가되지 않습니다. 또한 .format은 REST의 일부가 아닌 Rails 및 기타 프레임 워크의 규칙입니다. HTTP를 MIME 또는 마이크로 포맷과 함께 콘텐츠 협상을 통해 완전히 구현해야합니다.
Chris McCauley
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.