REST API에서 컬렉션에 기존 항목을 추가하는 가장 좋은 패턴은 무엇입니까?


23

실용적인 REST API를 디자인하고 있으며 기존 엔터티를 컬렉션에 추가하는 가장 좋은 방법을 고집했습니다. 내 도메인 모델에는 사이트 모음이있는 프로젝트가 포함되어 있습니다. 이것은 엄밀한 다 대다 관계이며 관계를 명시 적으로 모델링하는 엔티티 (예 : ProjectSite)를 만들 필요가 없습니다.

내 API를 통해 소비자는 기존 사이트를 프로젝트에 추가 할 수 있습니다. 내가 끊어지고있는 곳은 내가 정말로 필요한 유일한 데이터는 ProjectId와 SiteId라는 것입니다. 나의 초기 아이디어는 :

1. POST myapi/projects/{projectId}/sites/{siteId}

그러나 나는 또한 생각했다

2. POST myapi/projects/{projectId}/sites

JSON 엔터티로 전송 된 Site 엔터티

옵션 1은 간단하고 작동하지만 옳지 않은 느낌 이며이 패턴을 따르지 않는 다른 관계가있어 API에 불일치를 추가합니다.

옵션 2는 더 나아지지만 두 가지 우려가 있습니다.

  • 새 사이트가 게시되면 (사이트 ID = 0) 사이트를 만들거나 예외를 발생시켜야합니까?
  • 관계를 만들려면 ProjectId 및 SiteId 만 있으면되므로 사이트에 다른 속성에 대한 데이터가 잘못되었거나 누락 될 수 있습니다.

세 번째 옵션은 관계를 작성하고 삭제하기위한 단순한 엔드 포인트를 제공하는 것입니다. 이 엔드 포인트는 ProjectId 및 SiteId 만 포함하는 JSON 페이로드를 예상합니다.

어떻게 생각해?



@RoryHunter이 링크에는 흥미로운 토론이 있지만 내 불확실성을 제거하는 것은 없습니다. 나는 특히 받아 들여진 대답은 "당신은 옳게 이해했다"고 말합니다. 그리고 2 위 (큰 마진에도 불구하고)는 "간단히 말해서, 당신은 이것을 완전히 뒤로하고 있습니다."
Jamie Ide

클라이언트가 컬렉션에 추가되는 ID를 제어하므로 POST 대신 PUT을 사용하지만 첫 번째 옵션은 좋습니다. 옵션 2에 대한 첫 번째 관심사는 전적으로 귀하에게 달려 있습니다. 새로운 사이트를 원하지 않으면 예외를 던지지 말고 4xx 코드 중 하나를 반환하십시오. 두 번째 관심사는 여기도 없습니다. 추가를 허용하지 않는 한 전체 사이트를 게시해서는 안됩니다. 기존 사이트를 추가하면 사이트를 수정할 때만 ID를 가져야하지만 "ProjectSite"컬렉션 만 (별도의 리소스를 만들지 않더라도) 있어야합니다.
Marjan Venema

답변:


14

POST는 "append"동사 및 "processing"동사입니다. PUT는 알려진 식별자에 대한 "만들기 / 업데이트"동사이며, 전체 대상 URI가 알려져 있기 때문에 여기에서 올바른 선택처럼 보입니다. projectId그리고 siteId아직 당신이하지 않는 새로운 ID를 생성하는 "모음에 POST"해야합니까 존재한다.

PUT의 문제점은 본문에 PUT중인 자원을 표시해야한다는 것입니다. 그러나 여기서는 리소스를 업데이트하는 대신 "프로젝트 / 사이트"컬렉션 리소스에 추가하려고합니다.

누군가 기존 사이트의 전체 JSON 표현을 PUT하면 어떻게 되나요? 컬렉션 업데이트하고 개체 를 업데이트해야합니까 ? 당신은 그것을 지원할 수 있지만 의도는 아닌 것 같습니다. 말했듯이

실제로 필요한 유일한 데이터는 ProjectId 및 SiteId입니다.

오히려 siteId컬렉션에 POSTing을 시도하고 POST의 "append"및 "process"특성에 의존합니다.

POST myapi / projects / {projectId} / sites

{ 'id': '...'}

Site resource가 아닌 sites collection 리소스를 수정하고 있으므로 원하는 URI입니다. POST는 "append / process"를 알고 해당 id를 가진 요소를 프로젝트 사이트 모음에 추가 할 수 있습니다.

그럼에도 불구하고 JSON을 없애고 ID를 생략하여 프로젝트를위한 새로운 사이트를 만들 수 있습니다. "No id"== "처음부터 생성하십시오". 그러나 컬렉션 URI가 id를 얻지 못하면 다른 일이 발생하지 않아야합니다.

흥미로운 질문입니다. :)


POST가 작성 용이고 PUT이 업데이트 용이라고 믿지만, 결론은 어제 끝났습니다. 좋은 점은 Web API의 속성 라우팅 덕분에 ProjectSites 컨트롤러에 코드가 있으므로 코드가 잘 구성되어 있다는 것입니다.
Jamie Ide

나는 당신이 POST대신 PUT또는 PATCH여기 에 사용해야하는 결정적인 이유 는 당신이 자원 Site에 넣을 전체 엔티티 가 없기 때문이라고 생각합니다 sites. 컬렉션에 추가하기 위해 처리해야하는 ID 만 있습니다.
호감

4

우리는 이런 Patch방법 으로이 방법 을 사용합니다 . 원하는 것은 기존 프로젝트를 수정하여 사이트를 추가하는 것입니다.

이런 식으로 작동합니다

PATCH myapi/projects/{id} 

요청 본문에서 Site (s) 엔티티를 JSON / JSONArray로 사용합니다.

그렇게하면 필요한 경우 동일한 URL을 사용하여 프로젝트의 다른 부분을 수정할 수 있습니다. 구현의 코드는 리소스의 부분 수정을 처리 할 수있을 정도로 지능적이어야합니다.


재미있는 접근법. 나는 "풍부한"(즉, 의존도가 높은) 오래된 도메인 모델을 가지고 있으며 프로젝트에는 특히 많은 컬렉션이 있습니다. 요청에있는 엔티티 유형을 감지하는 것은 어려운 일이며 실제 목표에 맞지 않습니다.
Jamie Ide

왜 도전? 이러한 제한 사항이 있으면 언제든지 보내는 것을 명시 적으로 만드는 JSON을 사용할 수 있습니다 ...와 같이 {"sites": [], "other-stuff": {}}모든 "subjsons"를 매우 쉽게 처리하도록 코드를 분기 할 수 있습니다. 그것은 실제로 당신의 특정 문제에 달려 있지만, 이런 종류의 것들을 위해 특별히 고안된 PATCH를 사용하는 것이 좋습니다.
juan

내가 볼 수있는 단점은 1) API는 어떤 컬렉션이 변경을 허용하는지 명시 적으로 통신하지 않습니다. 2) 웹 API 매개 변수 바인딩을 활용할 수 없습니다. 3) 큰 스위치 또는 if 문.
Jamie Ide

다른 곳에서 사용 된 패치 방법을 본 적이 없습니다.
NimChimpsky

PATCH또한 전체 엔티티가 일부 엔티티를 가리키는 ID가 아닌 값으로 전달 되지 않을까요 ?
호감
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.