페이로드에 자원 ID를 포함 시키거나 URI에서 파생 시키려면


13

API를 설계 할 때 PUT 페이로드에 업데이트중인 리소스의 ID가 포함되어야하는지에 대한 문제가 제기되었습니다.

이것이 우리가 현재 가지고있는 것입니다 :

PUT /users/123 Payload: {name: "Adrian"}

경로 코드는 URI에서 ID를 추출하고 업데이트를 계속합니다.

API의 첫 번째 사용자는 페이로드에서 ID를 허용하지 않는 이유에 대해 의문을 제기합니다.

PUT /users/123 Payload: {id: 123, name: "Adrian"}

허용하지 않는 이유는 페이로드와 URI에서 ID가 복제 되었기 때문입니다.

이것에 대해 좀 더 생각하면 리소스를 URI에 연결합니다.

URI에 ID가 없으면 페이로드를 수정해야합니다.

PUT /no/id/here Payload: {name: "Adrian"} < What user???

하지 말아야 할 이유가 있습니까?

답변:


14

당신이하는 가정 통일 부부로 자원 받는 식별자 자원 .

REST가 HTTP로 구현되면 GET을 사용하여 자원의 현재 값을 검색하고 PUT을 사용하여 새 값을 설정하십시오. GET에는 페이로드가 없으므로 리소스는 URI로 식별해야합니다. 그리고 PUT은 논리적으로 동일한 URI에 대해 수행되며 페이로드는 다음 GET이 리턴하려는 것과 정확히 일치해야합니다.

다른 URI에 POST를 사용할 수 있지만 GET과 불필요하게 비대칭 적이므로 덜 이해가됩니다. 공통 URI에 대한 POST는 새 자원 ( POST /users/new, payload : {name: "Adrian"}, response {id: 345, name: "Adrian"}) 을 작성하는 데만 의미가 있지만, dem 등성이 아니므 로 피해야합니다. REST를 위해 노력하고 있다면¹. 대신 한 번의 호출로 ID를 예약 한 다음 PUT을 사용하여 새 ID를 설정해야합니다. 첫 번째 요청이 실패하면 결국 ID 예약이 시간 초과되고 PUTdem 등성이 기 때문에 내결함성이 있습니다 . 또는 클라이언트 생성 UUID를 사용하십시오.


¹ REST의 정의는 dem 등성에 대해 아무 말도하지 않으므로 비등 전성 연산이있는 경우 REST가 아니라고 실제로 말할 수는 없습니다. i 등원 (imdempotent) 요청을 고수한다는 것은 요청을 복잡하게하지 않으면 서 더 신뢰할 수있게한다는 사실을 바꾸지 않습니다.


3
내가 아는 한 POST 요청은 dem 등 할 필요가 없습니다. 따라서 게시하는 데 아무런 문제가 없습니다 /users( 'new'를 추가 할 필요가 없습니다).
lex82

답장을 보내 주셔서 감사합니다. 모든 요청에 ​​i 등성을 갖는 것이 좋은 기능이지만 누가 REST API에 필요하다고 말합니까? 확실히 스스로 RESTful을 호출하는 많은 API는 비등 전적인 POST 요청을 허용합니다 (특히 서버가 새 자원에 대한 ID를 생성하는 경우). 그러나 REST의 매우 엄격한 정의를 적용하더라도 위의 예와 같이 i 등식이 아닌 POST로 어떤 아키텍처 제약 조건이 위반되는지 알 수 없습니다.
lex82

제약 조건을 위반하는 POST 요청을 이미지 할 수 있습니다. 리소스를 컬렉션에 게시하고 서버에서 ID를 결정하게하는 것이 REST 제약 조건을 위반하는 이유를 모르겠습니다.
lex82


3
POST의 전체 아이디어는
dem 등하 지 않아야합니다

2

이것에 대해 좀 더 생각하면 리소스를 URI에 연결합니다.

URI에 ID가 없으면 페이로드를 수정해야합니다.

PUT / no / id / here 페이로드 : {name : "Adrian"} <어떤 사용자 ???

하지 말아야 할 이유가 있습니까?

이 질문에 대한 답변은 고객이 ID를 변경할 수 있도록 허용할지 여부에 따라 다릅니다.

클라이언트가 PUT을 통해 ID를 변경할 수 있으면 리소스의 URI가 변경되므로 리소스가 이전 URI에 액세스 할 때마다 301 Moved Permanently를 제공해야합니다.

예를 들어

/users/123

클라이언트는 다음을 리소스에 PUT합니다.

{id: 222, name: "Adrian"}

자원이 업데이트되었고 URI가 이제

/users/222

LocationPUT 응답 의 필드는 새 URI를 포함해야하며, 이동 하면 Location 필드가 새 자원을 가리키는 응답 /users/123을 받아야 합니다.301/users/222

대부분의 경우 실제로는 클라이언트가 ID를 변경할 수 있기를 원하지 않습니다. 꽤 빨리 지저분해질 수 있습니다. 이 경우 ID는 서버 만 변경할 수있는 것으로 클라이언트가이 상태를 업데이트 할 수 없으므로 PUT 본문에서 제외해야합니다.

동일한 리소스에서 다른 URI를 요구하는 경우 다음과 같이 말합니다.

/users/adian_lync

해당 자원이 존재하지 않으면 서버는 자원을 작성하고이를 수행 할 때 ID를 작성해야합니다.


1
페이로드에서 ID의 배치에 의문을 제기 한 이유는 Backbone.js가 기본적으로 PUT 요청에서 ID를 전달했기 때문입니다. 우리는 그 일이 일어나지 않도록 막을 수 있지만 이제 이것이 이것이 기본 행동 인 이유를 알고 싶습니다.
Adrian Lynch

1
Backbone.js에 익숙하지 않은 것 같습니다. ID가 URL에 포함되어 있으면 불필요합니다. 아마도 개발자들에 대한 감독
Cormac Mulhall
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.