편안한 POST 응답을위한 '최상의'실습


217

그래서 여기에 새로운 것은 없습니다. 나는 약간의 설명을 얻으려고 노력하고 있으며 다른 게시물에서 찾을 수없는 것 같습니다.

다음과 같이 새 리소스를 안정적으로 만들고 있습니다.

/books (POST)

시체와 함께 :

{
  title: 'The Lion, the Witch and the Wardrobe',
  author: 'C. S. Lewis'
}

새 리소스의 Location 헤더와 함께 201 (Created)을 반환해야한다는 것을 알고 있습니다.

Location: /books/12345

내가 스스로 대답 할 수없는 질문은 서버가 몸에 돌아와야하는 것입니다.

나는 종종 이러한 유형의 응답을 수행했습니다.

{
  id: 12345,
  title: 'The Lion, the Witch and the Wardrobe',
  author: 'C. S. Lewis'
}

나는 몇 가지 이유로 이것을했다 :

  1. angularjs와 같은 프론트 엔드 프레임 워크 용 API를 작성했습니다. 내 특별한 경우에는 앵귤러 리소스를 사용하고 있으며 리소스를 찾으려면 ID 만 필요합니다. 응답 본문에 ID를 반환하지 않으면 Location 헤더에서 ID를 구문 분석해야합니다.
  2. 모든 책의 GET에서 나는 보통 id뿐만 아니라 전체 객체를 반환합니다. 이런 의미에서 내 클라이언트 코드는 ID를 가져올 위치 (위치 헤더 또는 본문)를 구별하지 않아도됩니다.

이제는 내가 실제로 회색 영역에 있다는 것을 알고 있지만 대부분의 사람들은 전체 리소스를 반환하는 것이 '나쁜'습관이라고 말합니다. 그러나 서버가 리소스에 정보를 변경 / 추가하면 어떻게 될까요? 그것은 분명히 ID를 추가하지만 타임 스탬프와 같은 다른 것을 추가 할 수도 있습니다. 전체 리소스를 반환하지 않으면 POST를 수행하고 ID를 반환 한 다음 클라이언트가 GET을 수행하여 새 리소스를 얻는 것이 좋습니다.


나는 개인적으로 POST 응답을 위해 빈 바디를 선호합니다. RESTful Location 헤더 값이 URI (고유 자원 식별자)가 아니어야합니까? 따라서 ID로 사용하고 서버 내부 ID를 파악하기 위해 구문 분석하지 않아야합니다. RESTful API 소비자 인 IMO는 제공된 서버가 리소스를 찾는 위치를 추측하여 제공된 경로를 사용하지 말고 제공된 하이퍼 링크를 사용하여 탐색해야합니다. 반복하면 네트워크 리소스 낭비가 심해집니다.
ch4mp

1
Create / Insert, Status 201-CREATED, Header Location → localhost : 8080 / employees / 1 (참조 : here )
Hassan Tareq

답변:


129

업데이트에서 전체 객체를 반환하는 것은 그다지 중요하지 않지만 전체 객체를 만들 때 반환하는 것이 일반적인 사용 사례에서 나쁜 습관이되는 이유는 거의 알 수 없습니다. 이것은 최소한 ID를 쉽게 얻고 관련성이있을 때 타임 스탬프를 얻는 데 유용합니다. 이것이 실제로 Rails로 스캐 폴딩 할 때 얻는 기본 동작입니다.

초기 POST로 얻을 수있는 데이터를 얻기 위해 ID 만 반환하고 GET 요청을 수행하면 아무런 이점이 없습니다.

어쨌든 API가 일관된 한 귀하의 요구에 가장 잘 맞는 패턴을 선택해야한다고 생각합니다. REST API를 빌드하는 올바른 방법은 없습니다 (imo).


26
나는 이것이 오래되었다는 것을 알고 있지만 POST 후에 GET을 사용한다는 설득력있는 주장을 할 수 있습니다. http / 1.1 스펙에서 모든 히스토리 도구는 GET 응답에서 전달 된 캐시 설정을 무시할 수 있습니다. 따라서 사용자가 POST로 업데이트 한 후 브라우저에서 뒤로 단추를 사용하여이 페이지로 돌아 가면 오래된 파일을 사용할 수 있습니다 원래 GET에서 캐시 된 데이터 따라서 GET을 재사용하면 캐시를 업데이트하고 페이지가 떠났을 때 페이지가 어떻게 보이는지 더 나은 스냅 샷을 얻을 수 있습니다.
Shaded

8
@Shaded API가 앱에서도 사용되도록 설계된 경우 두 가지 요청에 대한 주장이지지되지 않습니다. 일반적으로 모델 유형의 객체를 메모리에 유지하여 데이터를 캐시합니다. 일반적으로 POST 요청에 대한 응답으로 수행됩니다. 그리고 브라우저와 관련하여 POST 요청에 대한 응답은 여전히 ​​GET API 끝 점이있는 한 실제로 아프지 않습니다.
Jeehut

나는 Daniel이 여기에 말한 것을 구독합니다. Spring Data와 같은 성숙한 프레임 워크를 확인하더라도 지속 된 후에는 항상 전체 객체를 반환합니다. 클라이언트에서는 동일한 정보를 얻기 위해 서버 왕복을 저장하는 것이 좋습니다.
frandevel

205

새로운 객체를 반환하는 것은 "Uniform Interface-표시를 통한 자원 조작"의 REST 원칙에 적합합니다. 완전한 객체는 생성 된 객체의 새로운 상태를 나타냅니다.

API 디자인에 대한 훌륭한 참조 자료는 다음과 같습니다. 실용적인 RESTful API 디자인을위한 모범 사례

여기에 귀하의 질문에 대한 답변이 포함되어 있습니다 : 업데이트 및 생성은 리소스 표현을 반환해야합니다

그것은 말한다 :

API 소비자가 업데이트 된 표현을 위해 API에 다시 충돌하지 않도록하려면 API가 응답의 일부로 업데이트 된 (또는 생성 된) 표현을 반환하도록하십시오.

나에게는 실용적으로 보이고 위에서 언급 한 REST 원칙에 적합합니다.


6
관련 객체 전체를 반환하는 것은 어떻습니까? 이런 식으로 서버 측에서 가능한 정렬을 수행 할 수 있으며 프론트 엔드 구현을 용이하게합니다
phil294

2
그러나 이러한 모범 사례는 최선의 방법이 아닙니다. 저자는 다른 원칙과 동일한 HATEOAS가 "준비되지 않았기 때문에"사용해서는 안된다고 진술했다. 모든 RESTful 원칙은 특정 구현이 아니라 건축 설계 원칙이므로 HATEOAS는 "준비"되지 않습니다. 인용 된 참고 문헌은 RESTful API에 대한 저자의 비전에 관한 것으로 HATEOAS를 삭제하여 RESTful하지 않습니다. 이것이 최고의 참조가 아닌 이유입니다. :)
marcinn

1
@marcinn-원래 질문에 'Best'가 인용되어 있음을 알 수 있습니다.이 분야에 대해 많은 의견이 있기 때문에 추측합니다. 내가 지적한 참조는 내가 실용적으로 찾은 것입니다. 더 나은 참조가 있으면 공유하십시오. 나는 항상 더 많은 것을 배울 수 있습니다.
grahamesd September

@grahamesd 구현은 건축 디자인의 원리 / 패턴과는 다릅니다. 언젠가 HATEOAS가 준비 될 것으로 기대할 수는 없지만 많은 사람이 수용 할 수있는 구현을 만들 가능성이 있습니다. Vinay는 또한 http 메소드를 URL 및 특정 작업 (CRUD)에 매핑하는 것에 대해 썼습니다 .URL 접두어를 사용하여 버전을 지정하는 것이 더 실용적이며 쿼리 매개 변수로 필터링하는 것이 좋은 방법이라고 썼습니다. RESTful 아키텍처와 관련이 있습니다. 그는 일종의 계약에 대해 썼습니다. HTTP API에는 문제가 없지만 RESTful이라고 부르지 마십시오.
marcinn

- 다음은 @grahamesd이 설명하는 몇 가지 게시물입니다 medium.com/@andrea.chiarelli/... - restfulapi.net
marcinn
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.