2009-09-15 4 views
19

리소스가 카운터를 가지고 있습니다. 예를 위해,의 자원 프로필 부르 자, 카운터는 전망 해당 프로필에 대한의 수입니다.리소스 카운터를 RESTful 방식으로 증가시킵니다. PUT 대 POST

REST wiki 당 PUT 요청은 자원 생성 또는 수정에 사용되어야하며 멱등원이어야합니다. 이름을 무언가로 설정하고 결과가 변경되지 않는 PUT 요청을 발행 할 수 있기 때문에 프로필 이름을 업데이트하는 경우 해당 조합을 사용할 수 있습니다. 이러한 표준 PUT 요청을

, 나는 브라우저가 같은 것을 할 수있다 : 호출 할 때마다 카운터가 발생합니다

PUT /profiles/123/?counter=views 

: 카운터를 증가 들어

PUT /profiles/123?property=value&property2=value2 

을, 하나는 URL과 같이 호출 증분되고있다. 엄밀히 말하면 업데이트 작업이지만 idempotency를 위반합니다.

지도/우수 사례를 찾고 있습니다. POST로 이것을 수행하고 있습니까?

답변

8

프로필의보기를 추적하기 위해 다른 리소스를 시스템에 추가 할 수도 있습니다. "보기"라고 부를 수도 있습니다. 프로필에 보는

추가하려면

GET/정보/123/viewings :

프로파일의 모든 Viewings을 보려면

POST/정보/123/viewings, 당신을 #here 요청 본문에 사용자 지정 미디어 유형을 사용하여 세부 정보를 제출하십시오.

기존보기를 업데이트하려면 다음

PUT/사용자가 만든 사용자 정의 용지 유형을 사용하여 요청 본문에보기의 viewings/815 # 개정 제출할 속성. 당신 때문에 ', 또한

DELETE/viewings/815

:

(815)는보기를 삭제하려면/

GET/viewings :

은보기의 세부 사항으로 드릴 다운하려면 모범 사례를 요구하는 경우 RESTful 시스템이 hypertext-driven인지 확인하십시오.

대부분의 경우 URI에서 쿼리 매개 변수를 사용하는 데는 문제가 없습니다. 클라이언트에게 조작 할 수있는 아이디어를주지 마십시오.

대신 매개 변수가 모델링하려는 개념을 구현하는 미디어 유형을 만드십시오. 이 미디어 유형에 간결하고 모호하지 않고 설명이 포함 된 이름을 지정하십시오. 그런 다음이 용지 유형을 문서화하십시오. REST에서 쿼리 매개 변수가 노출되는 실제 문제는 실무가 종종 대역 외 통신을 유도하므로 클라이언트와 서버 간의 결합이 증가한다는 것입니다.

그런 다음 시스템에 균일 한 인터페이스를 제공하십시오. 예를 들어, 새 자원을 추가하는 것은 항상 POST입니다. 자원 업데이트는 항상 PUT입니다. 삭제는 DELETE이며 getiing은 GET입니다.

REST에 대해 가장 어려운 점은 미디어 유형이 시스템 디자인에 어떻게 적용되는지 이해하는 것입니다. Fielding은 시간이 없어서 Fielding이 자신의 논문에서 빠진 부분이기도합니다. 미디어 유형을 사용하는 미디어 유형을 사용하는 하이퍼 텍스트 기반 시스템의 특정 예를 보려면 Sun Cloud API을 참조하십시오.

+0

명확히하기 위해/viewings/815는 프로필의 815 번째보기를 참조합니다. 그렇습니까? –

9

나는 올바른 대답은 패치를 사용하는 것이라고 생각합니다. 나는 원자 카운터를 증가하는 데 사용해야 추천 다른 사람을 보지 않았다, 그러나 나는 RFC 2068 아주 잘 모든 것을 말해 믿는다

패치 방법은 엔티티의 목록이 포함 된 것을 제외하고는 PUT과 유사합니다 Patch 동작이 적용된 후 Request-URI로 식별 된 리소스 의 원본 버전과 리소스 의 원하는 내용 간의 차이. 차이점 목록은 엔터티의 미디어 유형으로 정의 된 형식의 이며 (예 : "application/diff") 서버가 원본을 버전으로 변환하는 데 필요한 변경 사항을 다시 만들 수있는 충분한 정보를 포함해야합니다. 리소스를 원하는 버전으로 업데이트하십시오.

그래서 나는 것, 프로필 (123)의 뷰 카운트를 업데이트 : (난 그냥 만들어)이 x-counters 미디어 타입이 field operator scalar 튜플의 여러 줄로 구성되어

PATCH /profiles/123 HTTP/1.1 
Host: www.example.com 
Content-Type: application/x-counters 

views + 1 

. views = 500 또는 views - 1 또는 views + 3은 모두 구문 적으로 유효합니다 (그러나 의미 상으로 금지 될 수 있음).

또 다른 미디어 유형을 만들 때 당황 스러울 지 모르지만 나는 POST/PUT 대안보다 더 정확하다고 겸허하게 제안합니다. 자기 자신의 URI, 특히 자신의 세부 정보 (필자가 가지고있는 모든 정보는 정수)를 사용하여 필드에 대한 리소스를 구성하는 것은 나에게 잘못되어 귀찮습니다. 유지할 카운터가 23 개라면 어떻게 될까요?

+1

"PATCH 동작이 적용된 후 원하는 내용의 리소스가 없으므로"표준 비트를 벗어납니다. 예 : 엔티티는 원하는 결과가 아니라 실행될 명령입니다. – Pocketsand

+0

@Pocketsand가 말한 바에 따르면,이 접근법은 "통일 인터페이스"제약 하에서 "표현을 통한 자원 조작"하위 제약 조건을 위반하지 않는가? 리소스를 조작하는 방법에 대한 지침을 보내는 대신 보려는 리소스의 표현을 다시 보내야합니다. – dayuloli

+0

@dayuloli 아직 해결책을 고민하고 있다면 [답변을 추가했습니다] (https://stackoverflow.com/questions/1426845/incrementing-resource-counter-in-a-restful-way-put-vs-post)/44852115 # 44852115)와 함께 가기로 결정한 것, 귀하의 필요에 부합 할 수도 있습니다. – Pocketsand

0

나는 Yanic과 Rich의 두 가지 접근 방식이 서로 관련이 있다고 생각합니다. 패치는 안전하거나 배제 할 필요는 없지만 동시성에 대해보다 강력 할 수 있습니다. Rich의 솔루션은 "표준"REST API에서 사용하기가 더 쉽습니다.

RFC5789를 참조하십시오 : [RFC2616], 섹션 9.1에 정의 된대로

패치, 안전으로 나무 등 적이지도 않습니다.

패치 요청이 또한 동일한 시간 프레임에서 동일한 자원에 두 PATCH 요청 사이의 충돌에서 나쁜 결과를 방지 멱등 가능하게하는 방식으로 발급 될 수있다. 일부 패치 형식이 알려진 기본 지점에서 작동해야하므로 여러 PATCH 요청의 충돌이 PUT 충돌보다 위험 할 수 있습니다. 그렇지 않으면 해당 패치가 리소스를 손상시킵니다.

0

이전의 답변을 평가 한 후 나는 사소한 작업에 대한 콘텐츠 형식으로 주위 KISS principle의 위반을했다 하구, 내 목적을 위해, PATCH가 부적절 결정. 난 단지 그래서 난 그냥 이런 짓을 N + 1을 증가하는 데 필요한 : ++이 메시지 본문과 하나 자원을 증가하기위한 명령으로 컨트롤러에 의해 해석됩니다

PUT /profiles/123$views 
++ 

.

나는 그것이 legal sub-delimiter을 그대로 자원의 필드/속성을 deliminate하는 $을 선택하고, 내 목적을 위해, 내 의견으로는, traversability의 느낌을 가지고 /보다 더 직관적 인 것 같았다.

관련 문제