Swagger 상속 및 구성


81

내 "단순화 된"API에서 모든 응답은 기본 "응답"클래스에서 파생 ( 상속 )됩니다. 응답 클래스되어 이루어지는 메타 가득 헤더, 상기 사용자가 요청하는 코어 데이터를 포함하는 본체. 응답 (JSON)은 모든 메타 데이터가 첫 번째 "레이어"에 있고 본문이 "본문"이라는 단일 속성이되도록 배치됩니다.

response
|--metadata attribute 1 (string/int/object)
|--metadata attribute 2 (string/int/object)
|--body (object)
    |--body attribute 1 (string/int/object)
    |--body attribute 2 (string/int/object)

다음 JSON을 사용하여이 관계를 정의하려고했습니다.

{
    ...
    "definitions": {
        "response": {
            "allOf": [
                {
                    "$ref": "#/definitions/response_header"
                },
                {
                    "properties": {
                        "body": {
                            "description": "The body of the response (not metadata)",
                            "schema": {
                                "$ref": "#/definitions/response_body"
                            }
                        }
                    }
                }
            ]
        },
        "response_header": {
            "type": "object",
            "required": [
                "result"
            ],
            "properties": {
                "result": {
                    "type": "string",
                    "description": "value of 'success', for a successful response, or 'error' if there is an error",
                    "enum": [
                        "error",
                        "success"
                    ]
                },
                "message": {
                    "type": "string",
                    "description": "A suitable error message if something went wrong."
                }
            }
        },
        "response_body": {
            "type": "object"
        }
    }
}

그런 다음 본문 / 헤더에서 상속되는 다양한 본문 / 헤더 클래스를 만들어 다른 응답을 만든 다음 관련 헤더 / 본문 클래스로 구성된 자식 응답 클래스를 만듭니다 (아래의 소스 코드 참조). 그러나 이것이 일을 수행하는 잘못된 방법이거나 내 구현이 잘못되었음을 확신합니다. swagger 2.0 사양 (아래 참조) 에서 상속의 예를 찾을 수 없었지만 구성 의 예를 찾았습니다 .

여기에 이미지 설명 입력

나는이 "차별 자"가 큰 역할을 할 것이라고 확신하지만 내가 무엇을해야하는지 잘 모르겠습니다.

질문

누군가가 swagger 2.0 (JSON)에서 구성 + 상속을 구현하는 방법을 보여줄 수 있습니까? 가급적이면 아래 예제 코드를 "수정"하면됩니다. 헤더의 "result"속성이 항상 "error"로 설정된 응답에서 상속하는 ErrorResponse 클래스를 지정할 수 있다면 좋을 것입니다.

{
    "swagger": "2.0",
    "info": {
        "title": "Test API",
        "description": "Request data from the system.",
        "version": "1.0.0"
    },
    "host": "xxx.xxx.com",
    "schemes": [
        "https"
    ],
    "basePath": "/",
    "produces": [
        "application/json"
    ],
    "paths": {
        "/request_filename": {
            "post": {
                "summary": "Request Filename",
                "description": "Generates an appropriate filename for a given data request.",
                "responses": {
                    "200": {
                        "description": "A JSON response with the generated filename",
                        "schema": {
                            "$ref": "#/definitions/filename_response"
                        }
                    }
                }
            }
        }
    },
    "definitions": {
        "response": {
            "allOf": [
                {
                    "$ref": "#/definitions/response_header"
                },
                {
                    "properties": {
                        "body": {
                            "description": "The body of the response (not metadata)",
                            "schema": {
                                "$ref": "#/definitions/response_body"
                            }
                        }
                    }
                }
            ]
        },
        "response_header": {
            "type": "object",
            "required": [
                "result"
            ],
            "properties": {
                "result": {
                    "type": "string",
                    "description": "value of 'success', for a successful response, or 'error' if there is an error",
                    "enum": [
                        "error",
                        "success"
                    ]
                },
                "message": {
                    "type": "string",
                    "description": "A suitable error message if something went wrong."
                }
            }
        },
        "response_body": {
            "type": "object"
        },
        "filename_response": {
            "extends": "response",
            "allOf": [
                {
                    "$ref": "#definitions/response_header"
                },
                {
                    "properties": {
                        "body": {
                            "schema": {
                                "$ref": "#definitions/filename_response_body"
                            }
                        }
                    }
                }
            ]
        },
        "filename_response_body": {
            "extends": "#/definitions/response_body",
            "properties": {
                "filename": {
                    "type": "string",
                    "description": "The automatically generated filename"
                }
            }
        }
    }
}

다이어그램 업데이트

내가 원하는 것을 명확히하기 위해 모든 응답이 response_header 및 response_body 개체의 조합을 사용하여 (구성)에 의해 구축 된 "응답"개체의 인스턴스화임을 보여주는 매우 기본적인 다이어그램을 아래에 만들었습니다. response_header 및 response_body 객체는 확장하여 모든 응답 객체에 삽입 할 수 있으며, 이는 기본 response_body 클래스의 filename_response_body 자식을 사용하는 filename_response의 경우에 수행됩니다. 오류 및 성공 응답 모두 "응답"개체를 사용합니다.

여기에 이미지 설명 입력


1
이다 구성에 대한 샘플,하지만 그것은 가치가 공유 아니다 나쁘지입니다. 사양이 어떻게 생겼는지 작업하겠습니다. 현재 UI는이를 지원하지 않지만 2.0에 대한 전체 지원이 제공되면 지원할 예정입니다.
Ron

1
들어가기 전에 한 가지 더-구성 또는 상속을 찾고 있습니까? 구성은 기본적으로 말하고 I have the properties of X and my own properties.있습니다. 상속은 관계를 암시합니다 X is my parent. I have its properties and my own.. 상속은 부모의 특정 모델 세트를 적용 할 수 있다고 말하고 싶을 때 유용합니다.
Ron

1
이 예제 를 통해 상속 구성 의 사용을 한 번에 보여주고 싶었습니다 . 분명히 나는 ​​둘 중 하나를 그 자체로 쉽게 사용할 수 있다는 것을 알고 있지만이 경우 모든 응답은 기본 "응답"클래스의 자식입니다. 그리고 응답 클래스는 헤더와 본문이라는 두 개의 다른 개체로 "구성"됩니다.
Programster

2
나는 명확하지 않았을 수 있습니다. 상속은 구성의 확장입니다. 상속이 있으면 구성이 있습니다. 컴포지션이 있다면 반드시 상속이있는 것은 아닙니다. 또한 샘플에서 "응답"모델은 어디에도 사용되지 않습니다. 나는 그것을 무시하고 어떻게 보일지 보여야할까요?
Ron

아, 상속과 구성 사이의 관계를 깨닫지 못했습니다. 따라서 상속을 사용하여 둘 다 표시하십시오. 사용되지 않는 응답 모델과 관련하여 요청이 응답하는 파일 이름 _response 하위의 "확장자"와 함께 사용해야합니다.
Programster

답변:


113

스웨거의 초보자로서 나는 예가 부족 하기 때문에 이해하기 쉬운 polimorphism과 구성에 대한 공식 문서를 찾지 못했습니다 . 인터넷을 검색 했을 때 유효한 경우 swagger 1.2를 참조하는 좋은 예가 많이 있습니다.extends

들어 자신감 2.0 나는에 좋은 예를 발견 GitHub의에 자신감 사양 원 이를 통해 구글 그룹

위의 소스를 기반으로 YAML 의 짧은 유효한 상속 예제 는 다음과 같습니다.

definitions:
  Pet:
    discriminator: petType
    required:
      - name
      - petType # required for inheritance to work
    properties:
      name: 
        type: string
      petType:
        type: string
  Cat:
    allOf:
      - $ref: '#/definitions/Pet' # Cat has all properties of a Pet
      - properties: # extra properties only for cats
          huntingSkill:
            type: string
            default: lazy
            enum:
              - lazy
              - aggressive
  Dog:
    allOf:
      - $ref: '#/definitions/Pet' # Dog has all properties of a Pet
      - properties: # extra properties only for dogs
          packSize:
            description: The size of the pack the dog is from
            type: integer

정말 감사합니다! 이것은 나를 위해 작동합니다. 에서는 editor.swagger.io약간의 버그가 있습니다. 모델 섹션에서 Pet모델을 여러 번 봅니다. 이 모델의 내용은 괜찮습니다. 이름 만 잘못되었습니다.
schellingerht

에서 @schellingerht editor2.swagger.io이 문제가 표시되지 않습니다
Shiplu Mokaddim

상속을 정의하는이 방법에서 찾은 유일한 문제는 생성 된 클래스에서 petType 속성이 약간 쓸모 없다는 것입니다. 비어 있습니다. 그러나 적어도 내가 생각했던 것처럼 클래스 계층 구조를 생성합니다. 감사!
xarlymg89

위와 같이 상속 json을 생성하려면 부모 및 자식 클래스에 다음과 같이 주석을 달아야합니다. @ApiModel (discriminator = "type", subTypes = {Cat.class, Dog.class}) public abstract class Animal {} @ ApiModel (parent = Animal.class) public calss Cat extends Animal {}
Janet

판별자는 Interface를 구현할 때만 Pet사용됩니까? 클래스 A가 클래스 B를 확장하면 우리도 사용해야합니까? 감사합니다
Bionix1441

23

나는 구성이 discriminator.

예를 들어, base Response:

definitions:
  Response:
    description: Default API response
    properties:
      status:
        description: Response status `success` or `error`
        type: string
        enum: ["success", "error"]
      error_details:
        description: Exception message if called
        type: ["string", "object", "null"]
      error_message:
        description: Human readable error message
        type: ["string", "null"]
      result:
        description: Result body
        type: ["object", "null"]
      timestamp:
        description: UTC timestamp in ISO 8601 format
        type: string
    required:
      - status
      - timestamp
      - error_details
      - error_message
      - result

다음과 같이 렌더링됩니다.

반응 시각화

그리고이를 확장하여 result필드의 사용자 정의 스키마를 구체화 할 수 있습니다 .

  FooServiceResponse:
    description: Response for Foo service
    allOf:
      - $ref: '#/definitions/Response'
      - properties:
          result:
            type: object
            properties:
              foo_field:
                type: integer
                format: int32
              bar_field:
                type: string
        required:
          - result

그리고 다음과 같이 올바르게 렌더링됩니다.

FooServiceResponse 시각화

참고 allOf작업이 충분하고 더 discriminator필드가 사용되지 않습니다. 이것은 작동하고 이것이 중요하기 때문에 좋습니다. 제가 생각하기에 도구는 discriminator필드 없이 코드를 생성 할 수 있습니다 .


나는 또한을 사용 allOf했지만 어떻게 든에서 openapi.yaml하위 클래스에 수퍼 클래스의 속성이 중복되는 방식으로 포함되어 있음을 알았습니다. 맞습니까?
Bionix1441

8

여기에있는 모든 답변은 이미 훌륭하지만 구성 대 상속 에 대한 사소한 메모를 추가하고 싶습니다 . Swagger / OpenAPI Spec 에 따르면 @oblalex가 올바르게 지적했듯이 구성 을 구현 하려면 allOf속성을 사용하는 것으로 충분 합니다 . 그러나 상속 을 구현 하려면 @ TomaszSętkowski 에서 allOfdiscriminator같이 with를 사용해야 합니다.

또한 API Handyman에서 구성상속 에 대한 Swagger 예제를 더 찾았습니다 . Arnaud Lauret 의 훌륭한 Swagger / OpenAPI 튜토리얼 시리즈의 일부이며 모두가 확인해야한다고 생각합니다.


1
@ 관련 링크를 게시하는 것이 좋은 시작이지만 실제로 유용한 답변이 되려면 링크에서 찾을 수있는 관련 텍스트도 인용해야합니다. 링크 전용 답변은 권장되지 않습니다. 링크가 자주 중단되기 때문입니다.
Stijn de Witt

3

공유 한 Swagger 2.0 표준 예제는 컴포지션 관계를 설명합니다. 특히 "일종의"수퍼 유형 / 하위 유형 관계를 캡처하지만 그 자체로는 다형성이 아닙니다.

Pet의 기본 정의를 입력 매개 변수로 참조한 다음 Cat을 선택하거나 입력 요청에 대한 값으로 Cat JSON 객체를 입력하고 Swagger UI에서이를 허용 할 수있는 경우입니다.

나는 이것을 직접 작동시킬 수 없었다.

내가 작업 할 수있는 최선의 방법은 기본 개체 (예 : Pet)에서 additionalProperties를 true로 설정하고 JSON 포인터 참조를 입력 스키마로 사용하여 Pet을 지정한 다음 마지막으로 내 Cat JSON 값 개체를 Swagger UI에 복사하여 붙여 넣는 것입니다. 추가 속성이 허용되므로 Swagger UI는 유효한 입력 요청 페이로드를 생성했습니다.


특정 해킹과 밀접하게 결합하여 작동하도록 만들고 싶지 않으면 와이어를 통해 다형성을 수행하지 않습니다 (또는 데이터 엔티티를 노출).
user1496062 2016

다형성은 상속에 의해 활성화되지만 상속을 사용할 필요는 없습니다. 논리적으로 상속은 "is-a"관계이고 composition은 "has-a"관계입니다. 구현 언어 및 도메인 사용 사례에 따라 둘 사이의 경계가 모호 할 수 있습니다. 그러나 그것이 출발점입니다. Fwiw, 판별 기는 다형성 유형의 역 직렬화를 가능하게합니다. 다른 접근 방식이 있습니다 (예 : Java 클래스 이름 포함). 그러나 동의했다, 이것들은 복잡하고 이식성이 없을 수있다. 예를 들어 파이썬 클라이언트는 Java 클래스 이름으로 무엇을할까요?
Charlie Reitzel
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.