POST 전에 미리보기를 표시하는 REST 엔드 포인트


17

REST 백엔드 및 HTML + JS 프론트 엔드로 구동되는 새로운 웹 응용 프로그램을 설계하고 있습니다.

하나의 엔터티를 변경하는 POST 메소드 가 하나 있습니다 (Config라고 부르십시오). 응용 프로그램의 많은 요소 상태에서 몇 가지 부작용이 있습니다. POST 가 이런 식으로 수행 되었다고 가정 해 봅시다 .

POST /api/config BODY {config: ....}

이로 인해 최종 사용자가 변경 사항을 알 수 있도록 변경하기 전에 미리보기를 표시하고 싶습니다.

내가 처음 생각한 것은 미리보기 를 위해 GET 끝점 을 만들어 엔티티의 새로운 상태의 본문을 보내는 것입니다. 이 방법:

GET /api/preview/items BODY {config: ....}

새로운 구성으로 아이템의 새로운 상태를 보여줄 수 있습니다.

GET /api/preview/sales BODY {config: ....}

새로운 구성으로 판매의 새로운 상태를 보여줄 수 있습니다.

응용 프로그램의 상태를 변경하지 않으므로 GET 동사 를 사용하는 것이 좋습니다 . 그러나 GET 요청 과 함께 요청 본문을 사용 하지 않는 것이 좋습니다 .

이것에 대한 좋은 연습이 있습니까? 다른 방법은 구성을 하나의 방법으로 초안으로 저장하고 다른 방법으로 결과를 표시하는 것이지만 추가 단계가 필요하며 서버에서 초안을 관리해야합니다.

POST /api/preview/config BODY {config: ....}

GET /api/preview/items?idPreviewConfig=1

정확히 어떤이 설정 될 수 있으며, 어떻게 영향을 미치는 않는 itemssales? 반환 된 엔터티의 표현에 영향을 미칩니 까?
Andy

구성 및 구성 변경으로 인해 항목과 판매가 모두 영향을받는다고 가정 해 봅시다.
Xtreme Biker는 Monica Monica를

그러나 변화는 무엇을 의미합니까? 리턴 된 엔티티 세트를 변경합니까? 반환 된 구조가 변경됩니까?
Andy

실제로 POST 구성에 따라 itemssales(구조가 아닌) 의 값을 변경합니다 .
Xtreme Biker는 Monica Monica를

그리고 구성은 정확히 얼마나 큽니까? 수백 킬로바이트 이상으로 성장할 수 있습니까?
Andy

답변:


27

HTTP에서 기본적으로 지원하기에는 너무 도메인별로 다릅니다.

대신 다음 중 하나를 수행 할 수 있습니다.

  1. 되세요 POST /api/config/preview. 서버 측에서 응용 프로그램은 실제 구성을 수정해서는 안되지만 실제 구성과 게시 한 구성을 결합하여 변경된 내용을 나타내는 결과를 반환한다는 것을 알게됩니다.

    나중에 사용자가 결과에 만족 POST /api/config하면 이전 요청과 동일한 페이로드를 포함 하는 포함 을 수행합니다 . 이것은 효과적으로 구성을 덮어 씁니다.

    이 방법의 장점은 현재 API를 크게 변경하지 않는다는 것입니다. 미리보기 기능이 필요하지 않은 클라이언트는 여전히 이전과 같이 항목을 업데이트 할 수 있습니다.

    단점은 본문이 크면 서버에 두 번 보내야한다는 것을 의미합니다. 이것이 당신의 경우라면, 다음 접근법을 사용할 수 있습니다.

  2. 되세요 POST /api/config/prepare임시 레코드에 전송 된 것을 기억하고 두 가지를 반환 : (예를 들어 임시 레코드의 ID 12345)와 변화의 미리보기.

    사용자가 결과에 만족 POST /api/config/commit/12345하면 변경 사항을 결정적으로 저장합니다. 그렇지 않은 경우 임시 레코드가 일정 시간 동안 유지 된 후 크론 작업에 의해 삭제 될 수 있습니다.

    이점은 여기서 다시 원본을 POST /api/config그대로 유지할 수 있으며 미리보기가 필요없는 클라이언트는 중단되지 않는다는 것입니다.

    단점은 (1) 임시 레코드 제거를 처리하는 것이 까다로울 수 있다는 것입니다 (1 시간이면 충분하다고 생각하는 이유는 무엇입니까? 만료 된 레코드?) 및 (2) 두 단계의 레코드 제출이 필요 이상으로 복잡 할 수 있습니다.

  3. 클라이언트 측에서 미리보기 로직을 ​​이동하십시오.


"이것을 유지하지 말고 what-if 만 보여주십시오"라는 헤더를 보내는 것은 어떻습니까? @ArseniMourzenko
marstato

1
@ marstato : 개인적으로, 나는 그 용도에 대한 HTTP 헤더를 좋아하지 않습니다. 다른 사람들에게는 이치에 맞을 수도 있지만 답변을 편집해도 괜찮습니다. 자신의 답변을 게시 할 수도 있습니다. 그러면 다른 사람이 답변을 공개 할 수 있습니다 (평판 점수를 얻음).
Arseni Mourzenko

옵션 1이 내 경우에 더 적합하다고 생각합니다. 따라서 미리보기 구성을 POST하면 정의 된 각 엔티티에 대한 미리보기 엔드 포인트를 정의하지 않고 결과가 변경됩니다. 합리적인 것 같습니다. 기술적으로 말해서 POST를 사용하여 서버를 변경하지 않는 것이 유일한 방법입니다. 제 경우에는 옵션 3을 사용할 수 없습니다.
Xtreme Biker는 Monica

1
@PedroWerneck 당신은 그것을 확장 할 수 있습니까? 옵션 2는 다른 엔터티 (초안 구성)를 정의하고 상태 비 저장 방법을 제공하는 것으로 보입니다.
앤드류는 모니카 복원 모니카

1
@PedroWerneck 서버에 설정을 저장하는 것과 같은 방식으로 상태 저장입니다. 따라서 애플리케이션은 사용자의 관점에서 이미 상태가 유지되므로이 기능을 추가 할 수있는 모든 옵션도 있습니다.
jpmc26

10

REST에서 다른 API 호출에 특정 HTTP 동사를 사용하는 요점은 기존 HTTP 메커니즘과 기대를 활용하는 것입니다.

이 경우 GET을 사용하면 두 가지 모두에 반대되는 것처럼 보입니다.

A. 고객은 GET이 포함 된 바디를 포함해야합니까? 예기치 않은

B. 서버는 신체에 따라 get에 다른 응답을 반환합니까? 사양 및 캐싱 메커니즘 중단

RESTful 질문으로 어려움을 겪고 있다면 내 규칙은 나 자신에게 묻는 것입니다.

"모든 것을 위해 POST를 사용하는 것보다 이것이 더 낫습니까?"

즉각적이고 명백한 이점이 없다면 JUPS (Just Use POST Stupid) 전략을 사용하십시오.



@Ewan ...이 실용적인 접근 방법인지 여부에 관계없이 POST에 모든 것을 사용하는 경우 실제로 RESTful하지는 않습니다.
Allenph

1
POST가 모든 방법에 적합한 선택이 아닌 한. 그리고 적용 할 수있는 객관적인 규칙이 아니라, 지침에 지나지 않는 것에 대한 주관적인 해석을 논의 할 것입니다.
Ewan

6

서버에 "이것을 유지하지 말고 결과를 보여줄 것만 보여줘"라는 헤더를 보낼 수 있습니다. 예 :

POST /api/config HTTP/1.1
Host: api.mysite.com
Content-Type: application/json
Persistence-Options: simulate

{
   "config": {
      "key": "value"
   }
}

서버가 응답 할 수있는 대상 :

HTTP/1.1 200 OK
Persistence-Options: simulated
Content-Type: application/json

-- preview --

DB와 작업 단위 기반 O / RM 및 / 또는 요청 당 트랜잭션을 사용하는 경우 특정 엔드 포인트에 대한 작업을 요구하지 않고 모든 엔드 포인트에 대해이 기능을 쉽게 구현할 수 있습니다. 요청에 해당 옵션이 포함 된 경우 트랜잭션 / 작업 단위를 커밋하는 대신 롤백하십시오.



@PeterRader 좋은 지적은X-
marstato를

천만에요. 시뮬레이션중인 엔티티를 "시뮬레이션"으로 표시해야합니까?
피터 레이더

아니; 그것이 시뮬레이션의 요점입니까? 헤더 값도 가능 none하지만 내 취향으로는 POST메소드 의 성격과 너무 모순됩니다 .
marstato

2

검색을 처리하는 것과 같은 방식으로 처리하는 것이 좋습니다. /api/config/preview새 미리보기를 만드는 POST 끝점을 설정합니다 . 그런 다음 api/config현재 구성을 편집 할 것인지 또는 단순히 전체 구성을 바꾸려는지 에 따라 PUT 또는 PATCH 엔드 포인트를 설정합니다 (이전의 경우 방금 만든 미리보기를 보내는 경우).


0

다른 좋은 답변과 함께 다른 옵션은 언급 한 것처럼 구성을 게시하고 롤백 프로세스를 사용할 수도 있습니다. 애자일 방법론과 마찬가지로보다 세분화되고 반복 가능하며 테스트 된 절차를 통해 변경에 대한 두려움을 줄이는 것이 더 좋으며, 필요할 때 백업을 제공하여 애플리케이션에 따라 위험을 거의 또는 전혀 줄이지 않습니다. .

그런 다음 전체 시스템에 영향을주는 구성 오류가있을 경우 더 적극적으로 처리하고 싶을 경우 서버 또는 클라이언트 관점에서 해당 시점의 변경 사항을 미리 보려고 노력하지 마십시오. 이 미리보기 기능을 개발하는 데 더 많은 비용이 드는 방법을 알 수 있지만 사용 사례에는 따로 따로 테스트 할 별도의 단계가 있습니다.


0

RFC6648 새로운 X-구문을 더 이상 사용하지 않으므로 새로운 헤더 필드를 보내려면 아이디어에 반대 투표해야합니다. REST는 아키텍처 스타일입니다. 우리가 이야기하는 것은 RESTful입니다. 그러나 지금은이를 무시할 수 있습니다.

REST는 대표적이며 (실제로 시뮬레이션에는 표현이 없음) Stateful (및 시뮬레이션은 커밋 될 때까지 상태가 아니므로) 시뮬레이션 범위와 같은 새로운 범위를 가져야합니다. 그러나 시뮬레이션에는 시뮬레이션 프로세스가 포함되어 있기 때문에 시뮬레이션 대신 에뮬레이션이라고합니다. 상태 저장은 시뮬레이션의 이상적인 솔루션 인 에뮬레이션 인 스탠딩 상태를 의미합니다. 따라서 URL에서 에뮬레이션이라고합니다. 이것은 좋은 해결책 일 수도 있습니다.

GET  /api/emulation - 200 OK {first:1, last:123}
POST /api/emulation/124 - 200 OK
GET  /api/emulation/124/config - 200 OK {config:{tax:8}}
PUT  /api/emulation/124/config {config:{tax:16}} - 200 OK {config:{tax:16}}
GET  /api/emulation/124/items - 200 OK [first:1, last: 3000]
GET  /api/emulation/124/items/1 - 200 OK {price:1.79, name:'Cup'}
--- show emulation ---
--- commit emulation ---
PUT /api/config {config:{tax:16}}
DELETE /api/emulation/124 - 200 OK

또 다른 접근 방법이 있습니다 .... HTML / JavaScript 클라이언트의 많은 요청너무 많은 요청을 생성 할 수 있으며 동시에 약 17 개의 요청 한도에 도달 할 수 있습니다 ( 이 페이지를 살펴보십시오 ). REST 사용을 교체 할 수 있으며 Lame 객체 상태를 제공하는 대신 풍부한 사용자 별 페이지 상태를 제공 할 수 있습니다. 예:

GET /user/123/config - 200 OK {user:'Tim', date:3298347239847, currentItem:123, 
                  roles:['Admin','Customer'], config:{tax:16}, unsavedChanges:true, ...}

친절한 관계

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.