RESTful 서비스의 비 CRUD 작업


106

비 CRUD 작업을 RESTful 서비스에 추가하는 "RESTful"방법은 무엇입니까? 다음과 같은 레코드에 대한 CRUD 액세스를 허용하는 서비스가 있다고 가정합니다.

GET /api/car/123           <- Returns information for the Car object with ID 123
POST /api/car              <- Creates a new car (with properties in the request)
PUT /api/car/123           <- Updates car 123 (with properties in the request)
DELETE /api/car/123        <- Deletes car 123    
POST /api/car/123/wheel/   <- Creates a wheel and associates it to car 123

자동차의 색상을 변경하려면 간단히 POST /api/car/123새 색상에 대한 POST 변수를 포함합니다.

그러나 내가 자동차를 구매하고 싶다고 가정 해 봅시다. 그 작업은 단순히 "사용자"레코드의 "소유 한 자동차"속성을 업데이트하는 것보다 더 복잡합니다. POST /api/car/123/purchase"purchase"가 본질적으로 메소드 이름 인, 과 같이 단순히하는 것이 RESTful 입니까? 아니면 PURCHASE대신에 사용자 지정 HTTP 동사를 사용해야 POST합니까?

아니면 CRUD가 아닌 작업이 완전히 REST 범위를 벗어 납니까?


5
자동차의 색상을 변경하는 경우 PATCH /api/car/123색상 매개 변수를 사용 PUT /api/car/123하여 전송하거나 전체 자동차 객체 를 사용 하여 전송하는 것이 좋습니다 . POST는 새 차를 만드는 아마 URL의 끝에 ID를 포함하지 않을 것임을 추론 할 것이다
RonnyKnoxville

답변:


65

구매 를 RESTful 사전 의 비즈니스 엔티티 또는 리소스 로 생각하십시오 . 즉, 구매는 실제로 새로운 리소스를 생성하는 것입니다. 그래서:

POST /api/purchase

새로운 주문을합니다. 세부 정보 (사용자, 자동차 등)는이 주소로 전송 된 콘텐츠 내에서 ID (또는 URI)로 참조되어야합니다.

자동차를 주문하는 것이 데이터베이스의 단순한 INSERT가 아니라는 것은 중요하지 않습니다. 실제로 REST는 데이터베이스 테이블을 CRUD 작업으로 노출하는 것이 아닙니다. 논리적 관점에서 주문 (구매)을 생성하지만 서버 측은 원하는만큼 많은 처리 단계를 자유롭게 수행 할 수 있습니다.

HTTP 프로토콜을 더욱 남용 할 수도 있습니다. Location헤더를 사용 하여 새로 생성 된 주문에 대한 링크를 반환하고 HTTP 응답 코드를 신중하게 선택하여 문제 (서버 또는 클라이언트 측) 등에 대해 사용자에게 알립니다.


3
REST는 리소스 상태를 조작하는 것이므로 모든 비즈니스 작업은 상태 CRUD 작업에 매핑되어야합니다. 어려운 비즈니스 운영 의미 체계 가 필요한 경우 SOAP 방식으로 이동해야합니다 (SOAP는 실제로 메시지 전달이지만 일반적으로 요청-응답 작업으로 구성됨).
Tomasz Nurkiewicz 2011

23
"자원으로 구매"디자인이 깔끔해 보입니다. 자원이 "맥주"이고 나는 서버가 그것을 마시길 원한다. ?! .. 또는 "맥주를 마시고", 어려운 사업 운영?! 더 진지하게, 작업을 자원으로 고려하는 RESTful 디자인입니까?! ..
Myobis

2
REST 서비스를 통해 "구매 주문 승인"을 어떻게 노출합니까? CRUD 방식으로 깔끔하게 수행 할 수없는 것은 SOAP에서 제공하는 작동 의미 체계가 필요하다는 점에서 @TomaszNurkiewicz가 옳다고 생각합니다. "구매 주문 승인"이 자체 모델 / 엔티티가 아닌 경우. 예 : POST / po-approval (요청에 PO 세부 정보 포함).
mydoghasworms 2014

2
REST 클라이언트의 관점에서 "구매 주문 승인"은 주문의 또 다른 업데이트 일뿐입니다. 예를 들어 "승인 됨"을 "true"로 변경하고 업데이트를 서버로 보냅니다. 서버는 아마도 많은 검사를해야 할 것이고 아마도 많은 다른 리소스를 업데이트 / 생성해야 할 것입니다. 그러나 그것은 서버 문제이며 클라이언트가 볼 수 없어야합니다.
AVee

2
@antinome : "클라이언트가이 중 일부를 알고 있다고 가정 해 보겠습니다."이 경우 REST를 수행하지 않는 경우 (하지만 여전히 유효하고 현명한 소프트웨어 일 수 있습니다!). REST는 그런 종류를 모르는 클라이언트를 생성하고 서버의 동작이 변경 되어도 작동하는 클라이언트를 생성 할 수 있도록 설계되었습니다. 여러분이하려는 것은 고전적인 RPC입니다. REST에 적합하도록 접근 방식을 검토하거나 RPC를 수행하고 SOAP와 같은 RPC 용 프로토콜을 사용하는 것을 수락해야합니다. REST는 RPC가되지 않기 위해 매우 노력하므로 RPC를 원하거나 필요로 할 때 절대 적합하지 않습니다.
AVee 2014-08-26

15

내가 이해하는 RESTful 방법은 새로운 HTTP 동사가 필요하지 않으며 수행해야 할 작업을 의미하는 명사가 어딘가에 있다는 것입니다.

차를 구입 하시겠습니까? 글쎄요

POST /api/order

2
PUT는 멱등 성이기 때문에 리소스 를 업데이트 하는 데 사용되지 않습니까? 즉, 원하는만큼 여러 번 호출 할 수 있지만 첫 번째 / 마지막 호출 만 중요합니다. 반면 POST는 리소스 를 만드는 데 사용되며 두 번 호출하면 실제로 두 개가 생성됩니다.
Tomasz Nurkiewicz 2011

1
@Tomas, 예, 오타. 원칙은 중요하지만 우리는 새로운 것, 순서, 새로운 동사가 필요하지 않습니다.
djna 2011-07-27

5

당신이 정말로하고있는 것은 주문을 만드는 것입니다. 따라서 주문 및 게시를위한 다른 리소스를 추가하고 주문 프로세스 중에 배치합니다.

메서드 호출보다는 리소스 측면에서 생각하십시오.

주문을 완료하려면 POST / api / order // complete 또는 이와 유사한 것입니다.


3

REST API가 의미론을 제공하는 것보다 훨씬 많은 방법으로 도움이된다고 생각합니다. 따라서 RPC 작업 스타일에서 더 의미가있는 일부 호출 때문에 RPC 스타일을 선택할 수 없습니다. 예는 두 장소 사이의 길 찾기를위한 Google지도 API입니다. 다음과 같이 표시됩니다. http://maps.googleapis.com/maps/api/directions/json?origin=Jakkur&destination=Hebbal

그들은 그것을 "findDirections"(동사)라고 부르고 그것을 연산으로 취급 할 수있었습니다. 오히려 그들은 "방향"(명사)을 리소스로 만들고 길 찾기 리소스에 대한 쿼리로 길 찾기를 처리했습니다 (내부적으로 방향이라는 실제 리소스가 없을 수 있으며 매개 변수를 기반으로 길 찾기를 찾기 위해 비즈니스 로직에 의해 구현 될 수 있음).


그것은 나쁜 예입니다. 이 경우 방향 (가능한 모든 방향, 무한한 수)은 리소스이고 매개 변수는 필터 일뿐입니다. 그러나 필터는 가져 오기 작업과 주문 또는 취소에만 의미가 있으므로 데이터를 변경하는 작업이므로 "구매"를 수행 할 수 없습니다
Tseng

2
구매는 주문이 생성되었음을 나타 내기 위해 본문에 json이있는 / order에 대한 POST입니다. cancel은 주문 상태 변경을 전달하는 json을 사용하여 / order에 PUT하여 이것이 멱 등성 업데이트임을 나타냅니다. 나는 여전히 자원 형식으로 표현할 수없는 작업을 실행해야합니다. 그래서 그런 예를보고 싶을 것입니다
Maruthi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.