상속을 사용하여 RESTful API를 모델링하는 방법은 무엇입니까?
RESTful API를 통해 노출해야하는 객체 계층 구조가 있는데 내 URL이 어떻게 구조화되어야하고 무엇을 반환해야하는지 잘 모르겠습니다. 모범 사례를 찾을 수 없습니다.
동물에서 물려받은 개와 고양이가 있다고 가정 해 보겠습니다. 나는 개와 고양이에 대한 CRUD 작업이 필요합니다. 나는 또한 일반적인 동물에 대한 수술을 할 수 있기를 원합니다.
내 첫 번째 아이디어는 다음과 같이하는 것이 었습니다.
GET /animals # get all animals
POST /animals # create a dog or cat
GET /animals/123 # get animal 123
문제는 / animals 컬렉션이 정확히 동일한 구조 (개와 고양이)를 갖지 않는 개체를 반환하고 가져올 수 있으므로 이제 "일관되지 않음"입니다. 서로 다른 속성을 가진 개체를 반환하는 컬렉션을 갖는 것이 "휴식"으로 간주됩니까?
또 다른 해결책은 다음과 같이 각 구체적인 유형에 대한 URL을 만드는 것입니다.
GET /dogs # get all dogs
POST /dogs # create a dog
GET /dogs/123 # get dog 123
GET /cats # get all cats
POST /cats # create a cat
GET /cats/123 # get cat 123
그러나 이제는 개와 고양이의 관계가 사라졌습니다. 모든 동물을 회수하려면 개와 고양이 자원을 모두 조회해야합니다. URL의 수도 새로운 동물 하위 유형마다 증가합니다.
또 다른 제안은 다음을 추가하여 두 번째 솔루션을 확장하는 것입니다.
GET /animals # get common attributes of all animals
이 경우 반환 된 동물은 모든 동물에 공통적 인 속성 만 포함하고 개별 및 고양이 별 속성을 삭제합니다. 이렇게하면 세부 사항은 적지 만 모든 동물을 검색 할 수 있습니다. 반환 된 각 객체에는 상세하고 구체적인 버전에 대한 링크가 포함될 수 있습니다.
의견이나 제안이 있으십니까?
내가 제안 할게:
- 리소스 당 하나의 URI 만 사용
- 특성 수준에서만 동물 구분
동일한 리소스에 여러 URI를 설정하는 것은 혼란과 예상치 못한 부작용을 일으킬 수 있으므로 결코 좋은 생각이 아닙니다. 따라서 단일 URI는 /animals
.
"기본"수준에서 개와 고양이의 전체 컬렉션을 처리하는 다음 과제는 이미 /animals
URI 접근 방식 을 통해 해결되었습니다 .
개와 고양이와 같은 특수 유형을 처리하는 마지막 과제는 미디어 유형 내에서 쿼리 매개 변수와 식별 속성의 조합을 사용하여 쉽게 해결할 수 있습니다. 예를 들면 :
GET /animals
( Accept : application/vnd.vet-services.animals+json
)
{
"animals":[
{
"link":"/animals/3424",
"type":"dog",
"name":"Rex"
},
{
"link":"/animals/7829",
"type":"cat",
"name":"Mittens"
}
]
}
GET /animals
-모든 개와 고양이를 얻고 Rex와 Mittens를 모두 반환합니다.GET /animals?type=dog
-모든 개를 가져오고 Rex 만 반환합니다.GET /animals?type=cat
-모든 고양이를 얻고, 장갑 만
그런 다음 동물을 만들거나 수정할 때 관련된 동물의 유형을 지정하는 것은 호출자에게 있습니다.
매체 유형: application/vnd.vet-services.animal+json
{
"type":"dog",
"name":"Fido"
}
위의 페이로드는 POST
또는 PUT
요청 으로 보낼 수 있습니다 .
위의 체계는 REST를 통한 OO 상속과 기본적으로 유사한 특성을 제공하며, 주요 수술이나 URI 체계의 변경없이 추가 전문화 (예 : 더 많은 동물 유형)를 추가 할 수있는 기능을 제공합니다.
나는 개와 물고기의 목록을 반환하는 / animals를 찾으러 갈 것입니다.
<animals>
<animal type="dog">
<name>Fido</name>
<fur-color>White</fur-color>
</animal>
<animal type="fish">
<name>Wanda</name>
<water-type>Salt</water-type>
</animal>
</animals>
유사한 JSON 예제를 쉽게 구현할 수 있어야합니다.
클라이언트는 항상 "이름"요소 (공통 속성)에 의존 할 수 있습니다. 그러나 "type"속성에 따라 동물 표현의 일부로 다른 요소가 있습니다.
이러한 목록을 반환하는 데 본질적으로 RESTful 또는 unRESTful은 없습니다. REST는 데이터를 나타내는 특정 형식을 규정하지 않습니다. 데이터에 어떤 표현이 있어야 하며 해당 표현의 형식은 미디어 유형 (HTTP에서 Content-Type 헤더)에 의해 식별됩니다.
사용 사례에 대해 생각해보십시오. 혼합 동물 목록을 표시해야합니까? 그럼, 혼합 동물 데이터 목록을 반환합니다. 개 목록 만 필요합니까? 글쎄, 그런 목록을 만드십시오.
/ animals? type = dog 또는 / dogs를 수행하는지 여부는 URL 형식을 규정하지 않는 REST와 관련이 없습니다. 이는 REST 범위 밖에있는 구현 세부 사항으로 남겨집니다. REST는 리소스에 식별자가 있어야한다고 만 명시합니다.
RESTful API에 더 가까워 지려면 하이퍼 미디어 링크를 추가해야합니다. 예를 들어 동물 세부 정보에 대한 참조를 추가하면 다음과 같습니다.
<animals>
<animal type="dog" href="/animals/123">
<name>Fido</name>
<fur-color>White</fur-color>
</animal>
<animal type="fish" href="/animals/321">
<name>Wanda</name>
<water-type>Salt</water-type>
</animal>
</animals>
하이퍼 미디어 링크를 추가하면 클라이언트 / 서버 커플 링을 줄일 수 있습니다. 위의 경우 클라이언트에서 URL 구성의 부담을 덜어주고 서버가 URL 구성 방법 (정의에 따라 유일한 권한 임)을 결정하게합니다.
이 질문은 OpenAPI의 최신 버전에 도입 된 최근 개선 사항의 지원으로 더 잘 대답 할 수 있습니다.
oneOf, allOf, anyOf와 같은 키워드를 사용하여 스키마를 결합하고 JSON 스키마 v1.0 이후 검증 된 메시지 페이로드를 얻을 수있었습니다.
https://spacetelescope.github.io/understanding-json-schema/reference/combining.html
However, in the OpenAPI (former Swagger), schemas composition has been enhanced by the keywords discriminator (v2.0+) and oneOf (v3.0+) to truly support polymorphism.
https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#schemaComposition
Your inheritance could be modeled using a combination of oneOf (for choosing one of the subtypes) and allOf (for combining the type and one of its subtypes). Below is a sample definition for the POST method.
paths:
/animals:
post:
requestBody:
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/Dog'
- $ref: '#/components/schemas/Cat'
- $ref: '#/components/schemas/Fish'
discriminator:
propertyName: animal_type
responses:
'201':
description: Created
components:
schemas:
Animal:
type: object
required:
- animal_type
- name
properties:
animal_type:
type: string
name:
type: string
discriminator:
property_name: animal_type
Dog:
allOf:
- $ref: "#/components/schemas/Animal"
- type: object
properties:
playsFetch:
type: string
Cat:
allOf:
- $ref: "#/components/schemas/Animal"
- type: object
properties:
likesToPurr:
type: string
Fish:
allOf:
- $ref: "#/components/schemas/Animal"
- type: object
properties:
water-type:
type: string
But now the relationship between dogs and cats is lost.
Indeed, but keep in mind that URI simply never reflects relations between objects.
I know this is an old question, but I'm interested in investigating further issues on a RESTful inheritance modeling
I can always say that a dog is an animal and hen too, but hen makes eggs while dog is a mammal, so it can't. An API like
GET animals/:animalID/eggs
is not consistent because indicates that all subtypes of animal can have eggs (as a consequence of Liskov substitution). There would be a fallback if all mammals respond with '0' to this request, but what if I also enable a POST method? Should I be afraid that tomorrow there would be dog eggs in my crepes?
The only way to handle these scenarios is to provide a 'super-resource' which aggregates all the subresources shared among all possibile 'derived-resource' and then a specialization for each derived-resource that needs it, just like when we downcast an object into oop
GET /animals/:animalID/sons GET /hens/:animalID/eggs POST /hens/:animalID/eggs
The drawback, here, is that someone could pass a dog Id to reference an instance of hens collection, but the dog is not an hen, so it would not be incorrect if the response was 404 or 400 with a reason message
Am I wrong?
참고URL : https://stackoverflow.com/questions/10880472/how-to-model-a-restful-api-with-inheritance
'Programing' 카테고리의 다른 글
Pandas read_csv 사용시 메모리 오류 (0) | 2020.10.13 |
---|---|
HTML5의 WebSocket을 사용하려면 서버가 필요합니까? (0) | 2020.10.13 |
SAML 서비스 제공 업체가되는 방법 (0) | 2020.10.13 |
ggplot2의 패싯에 일반 레이블을 어떻게 추가합니까? (0) | 2020.10.13 |
Viola-Jones의 얼굴 감지 기능으로 180k 기능 주장 (0) | 2020.10.13 |