하나의 요청으로 여러 항목을 만드는 RESTful 방법


122

주문을 수집하기 위해 소규모 클라이언트 서버 프로그램을 개발 중입니다. 나는 이것을 "REST (ful) 방식"으로하고 싶다.

내가하고 싶은 것은 :

모든 주문 라인 (제품 및 수량)을 수집하고 전체 주문을 서버로 보냅니다.

현재이 작업을 수행 할 수있는 두 가지 옵션이 있습니다.

  1. 각 주문 라인을 서버로 전송 : POST qty 및 product_id

옵션 2이므로 서버에 대한 요청 수를 제한하고 싶기 때문에 실제로이 작업을 수행하고 싶지 않습니다.

  1. 모든 주문 라인을 수집하여 한 번에 서버로 보냅니다.

옵션 2를 어떻게 구현해야합니까? 내가 가진 몇 가지 아이디어는 : 모든 주문 라인을 JSON 객체로 래핑하고 이것을 서버로 보내거나 배열을 사용하여 주문 라인을 게시하는 것입니다.

옵션 2를 구현하는 것이 좋은 생각입니까 아니면 좋은 습관입니까? 그렇다면 어떻게해야합니까?

좋은 습관이란 무엇입니까?

rest  post 

답변:


74

이에 접근하는 또 다른 올바른 방법은 리소스 컬렉션을 나타내는 또 다른 리소스를 만드는 것입니다. 예를 들어, 다음과 같은 엔드 포인트 /api/sheep/{id}가 있고 /api/sheep양 리소스를 생성 하기 위해 POST를 수행 할 수 있다고 가정합니다.

이제 대량 생성을 지원하려면에서 새 무리 리소스를 고려해야합니다 /api/flock(또는 /api/<your-resource>-collection더 의미있는 이름이없는 경우). 기억 자원 데이터베이스 또는 앱 모델에 매핑 할 필요가 없습니다 . 이것은 일반적인 오해입니다.

리소스는 데이터와 관련이없는 상위 수준의 표현입니다. 리소스에 대한 작업은 사용자에게 경고를 보내거나, 다른 관련 데이터를 업데이트하고, 수명이 긴 프로세스를 시작하는 등의 심각한 부작용이있을 수 있습니다. 예를 들어 파일 시스템이나 Unix ps명령을 REST API로 매핑 할 수 있습니다 .

자원을 운영하는 것이 부작용으로 다른 여러 엔티티를 생성하는 것을 의미 할 수도 있다고 가정하는 것이 안전하다고 생각합니다.


나는 이것에 동의한다. 리소스 컬렉션의 개념을 추상화하고 리소스처럼 취급해야합니다. 이 등의 작업을하고 시작하고자 할 때뿐만 아니라 미래에 더 많은 유연성을 제공합니다
villy393

이것이 올바른 접근 방식입니다. 이것은 POST Collection 요청을 중단하지 않습니다. 이후 단일 엔티티를 게시하는 데 사용됩니다. "별도의 대량 엔터티"를 사용하여 대량 요청을 보내는 것이 올바른 방법입니다.
분류기

2
나는 당신이 양과 무리로 이름을 짓는 API 끝점을 너무 좋아합니다! 어느 정도 추상화 된이 책은 거의 성경적 참조를 가지고 있습니다 . "나에게는이 우리에 속하지 않은 다른 양들이 있습니다. 그들도 데려 와야합니다. 그리고 그들은 내 목소리를들을 것입니다. 그리고 그들은 한 목자와 한 무리가 될 것입니다." 요한 복음 10:16.
Evgeny

1
흥미롭게도 사람들은 하나의 리소스를 만들고 싶을 때 URL에 (컬렉션의) 복수 형식을 사용하는 것이 좋습니다. 예를 들면 다음과 같습니다. / api / books에 POST를 보내 책을 만듭니다. 하지만 100 권의 책을 만들고 싶을 때 (json으로 단일 요청으로) 100 권의 책 컬렉션을 어떤 URL에 게시 하시겠습니까? 그것이 불안이 시작되는 곳입니다.
code4kix

@ 당신이 사용할 수 code4kix /api/book-group, /api/book-collection또는 이와 유사한.
miguelcobain

46

대량 작업 (예 : 일괄 생성)은 많은 시스템에서 필수적이지만 RESTful 아키텍처 스타일에 의해 공식적으로 해결되지는 않습니다.

제안한대로 컬렉션을 게시하는 것은 기본적으로 작동하지만 이러한 요청에 대한 응답으로 실패를보고해야하는 경우 문제가 발생합니다. 이러한 문제는 다른 원인으로 인해 여러 번 실패하거나 서버가 트랜잭션을 지원하지 않을 때 더욱 악화됩니다. 예를 들어 서비스 공급자가 LAN (WAN 아님)에 있거나 데이터가 비교적 작은 경우 성능 문제가없는 경우 서버에 100 개의 POST 요청을 보내는 것이 좋습니다. 단순하게 유지하고 별도의 요청으로 시작하고 성능 문제가있는 경우 최적화를 시도하십시오.


3
일괄 처리의 경우 오류에 대한 해결책을 직접 찾았습니까? 모바일 연결에서 100 개의 게시물 요청을 보내면 페이지 이음새가 나쁜 생각처럼 보입니다.
토마스 Ahle

오류를 배열에 추가하고 사용자를 419 충돌 오류 페이지로 라우팅하고 해당 오류를 클라이언트에 반환하고 오류 배열을 표시합니다. 자세한 내용은 아래 내 대답을 참조하십시오.
Eric Fuller

5
이건 말도 안돼. 문제는 많은 항목에 대한 주문을 보내는 것에 관한 것입니다. 많은 항목이 말했듯이 하나의 POST 요청의 엔터티에서 할 수 있습니다. 서버가이를 처리하는 방법은 완전히 다른 것입니다. 이 경우 주문 생성, 해당 주문에 대해 가능한 항목 채우기, 수행 할 수없는 세부 정보 채우기에 문제가 없다고 생각합니다. 이렇게하면 사용자가 주문을보고 N 개를 제외한 모든 항목이 주문에 추가되었지만 일부는 재고가 없거나 시스템에서 무엇을해야할지 알 수 없음을 확인할 수 있습니다. 또 다른 간단한 미만 사용자 친화적 인 옵션은 모든 것을 거부하는 것입니다
thecoshman

2
@thecoshman 3.25 년 동안 많은 변화가있었습니다. 질문에 대해 완전히 공식화 된 답변을 게시해야 할 것입니다.
dlamblin

3
그래 @dlamblin, 아마 많은 일을해야 ... 나는 어쩌면 어떤 단계에서 그것을 얻을거야 ...
thecoshman

9

Facebook은이를 수행하는 방법을 설명합니다. https://developers.facebook.com/docs/graph-api/making-multiple-requests

간단한 일괄 요청

배치 API는 JSON 배열로 표시된 논리적 HTTP 요청의 배열을받습니다. 각 요청에는 메서드 (HTTP 메서드 GET / PUT / POST / DELETE 등에 해당), relative_url (graph.facebook. com), 선택적 헤더 배열 (HTTP 헤더에 해당) 및 선택적 본문 (POST 및 PUT 요청 용). Batch API는 JSON 배열로 표시된 논리적 HTTP 응답 배열을 반환합니다. 각 응답에는 상태 코드, 선택적 헤더 배열 및 선택적 본문 (JSON 인코딩 문자열)이 있습니다.


1
이것은 매우 흥미로운 링크이며 제안 된 솔루션이 나에게 유용 할 것 같습니다. 어쨌든 StackOverflow에서 선호하는 답변은 링크가 변경되거나 사라질 수 있으므로 답변 본문에 솔루션의 개념을 설명하는 것입니다.
Jan Vlcinsky

7
즉, 정말 그 일의 페이스 북의 방법, 영업 등 반드시 편안하고없는 질문
0cd

관련없는 여러 요청을 함께 그룹화 할 때 Batch API (Google, Facebook 등-@PuneetArora)가 더 유용하다고 생각합니다. 하나의 항목을 생성하는 요청을 생성 한 다음 모든 요청을 그룹화하여 항목 컬렉션을 보내는 것은 "광기"(아인슈타인)입니다. 항목 컬렉션을 전달하는 요청을 생성하기 만하면됩니다.
tfmontague

8

당신의 아이디어는 나에게 타당 해 보입니다. 구현은 선호도의 문제입니다. JSON 또는 매개 변수 만 사용할 수 있습니다 ( "order_lines []"배열).

POST /orders

단일 작업 (주문 및 해당 라인)에서 한 번에 더 많은 리소스를 생성 할 것이기 때문에 각각의 리소스를 확인하고 모두 유효성 검사를 통과 한 경우에만 저장하는 것이 중요합니다. 거래에서해야합니다.


6

단일 연결 내에서 별도의 요청을 보내는 것이 더 낫다고 생각합니다 . 물론 웹 서버가이를 지원해야합니다.


5

나는 실제로 최근에 이것과 씨름하고 있으며 여기에 내가 노력하고 있습니다.

여러 리소스를 추가하는 POST가 성공하면 읽기로 추가 된 모든 리소스를 표시하는 페이지와 함께 200 OK (201을 고려했지만 사용자가 궁극적으로 생성 된 리소스에 도달하지 않음)를 반환합니다. -전용 또는 편집 가능한 패션. 예를 들어, 사용자는 단일 파일 입력으로 만 구성된 양식을 사용하여 여러 이미지를 선택하고 갤러리에 게시 할 수 있습니다. POST 요청이 전체적으로 성공하면 사용자에게 생성 된 각 이미지 리소스 표현에 대한 양식 집합이 제공되어 각각에 대한 세부 정보 (이름, 설명 등)를 지정할 수 있습니다.

하나 이상의 리소스 생성에 실패한 경우 POST 처리기는 모든 처리를 중단하고 각 개별 오류 메시지를 어레이에 추가합니다. 그런 다음 419 Conflict가 반환되고 사용자는 오류 배열의 내용과 제출 된 양식으로 돌아가는 방법을 제공하는 419 Conflict 오류 페이지로 라우팅됩니다.


-2

100 개의 주문 라인에 대한 HTTP 헤더를 보내지 않을 것입니다. 필요한 것보다 더 많은 요청을 생성하고 싶지 않습니다.

하나의 JSON 객체에있는 전체 주문을 server / order 또는 server / order / new로 서버에 보냅니다. 가리키는 것을 반환 : server / order / order_id

POST 대신 CREATE PUT 사용을 고려하십시오.


나는 그가 HTTP POST 방법을 언급한다고 가정합니다. CREATE HTTP 메소드와 같은 것은 없습니다.
Milan Novota

거기 없나요? 오 잠깐만 요. 대신 PUT이있었습니다.
Cheery 2009.01.04

22
도대체 콘텐츠 제작에 PUT을 사용하는 이유는 무엇입니까? 이것이 바로 HTTP POST 메서드의 용도입니다.
thecoshman

8
클라이언트가 webdav에서와 같이 리소스의 URI를 지정하도록하려는 경우 PUT를 사용하여 리소스를 생성합니다. 나는 포스터의 PUT 사용에 동의하지 않지만, 그 장소는 범위가 제한 될 수 있지만 리소스를 만드는 데는 장소가 있습니다.
user602525

2
참고 : 엔터티를 게시하면 엔터티가 요청에서 주소가 지정된 리소스의 하위 항목이되어야하며 멱 등성이 아닙니다. PUT는 주소의 엔티티를 대체하며 멱등입니다. 멱 등성 (단어?)은 소비자에게 중요한 기대치입니다.
누가 복음 Puplett
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.