IT TIP

Swagger 상속 및 구성

itqueen 2020. 10. 26. 21:37
반응형

Swagger 상속 및 구성


내 "단순화 된"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의 경우에 수행됩니다. 오류 및 성공 응답 모두 "응답"개체를 사용합니다.

여기에 이미지 설명 입력


스웨거의 초보자로서 나는 예가 부족 하기 때문에 이해하기 쉬운 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

나는 구성이 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

And it will be correctly rendered as:

FooServiceResponse 시각화

Note, that allOf is enough for this to work and no discriminator field is used. This is good, because it works and this is important, as I think, tools will be able to generate code without discriminator field.


All the answers here are excellent already, but I just want to add a minor note about composition versus inheritance. According to the Swagger/OpenAPI Spec, to implement composition, using the allOf property is enough, as @oblalex correctly points out. However, to implement inheritance, you need to use allOf with discriminator, as in the example by @TomaszSętkowski.

Also, I found some more Swagger examples of both composition and inheritance at API Handyman. They're part of an excellent Swagger/OpenAPI tutorial series by Arnaud Lauret that I think everyone should check out.


The Swagger 2.0 standard example you have shared depicts a composition relationship, specifically it captures an "is a kind of" super-type/sub-type relationship however it is not polymorphism in and of itself.

It would be if you could reference the base definition of Pet as an input parameter, then pick Cat or enter a Cat JSON object as the value for the input request, and have this acceptable to Swagger UI.

I could not get this to directly work.

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

참고 URL : https://stackoverflow.com/questions/27862407/swagger-inheritance-and-composition

반응형