stream浪者的inheritance和组成
在我的“简化”API中,所有响应都是从基础“响应”类派生( inheritance )。 响应类由填充了元数据的头部和包含用户请求的核心数据的主体组成。 响应(在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" } } }
然后,我尝试通过创build从body / headerinheritance的各种body / header类创build不同的响应,然后创build由相关的header / body类组成的子响应类(在源代码底部显示)。 但是,我确信这是做错事情的错误方式,或者我的实现不正确。 我一直无法在swagger 2.0规范 (如下所示)中findinheritance的例子,但find了组合的例子。
我很确定这个“鉴别者”有很大的作用,但不知道我需要做什么。
题
有人可以告诉我一个人应该如何在swagger 2.0(JSON)中实现组合+inheritance,最好是通过“固定”下面的示例代码。 如果我可以指定一个从响应inheritance的ErrorResponse类,那么标题中的“result”属性始终设置为“error”也是很好的select。
{ "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" } } } } }
图表更新
为了试图澄清我想要的内容,我创build了下面这个非常基本的图表,其目的是显示所有响应都是由(组合)使用response_header和response_body对象的任意组合构build的“响应”对象的实例。 response_header和response_body对象可以扩展并插入任何响应对象,这是在使用基本response_body类的filename_response_body子级的filename_response的情况下完成的。 错误和成功的响应都使用“响应”对象。
作为一个初学者,我没有find关于多态性和组成的官方文档 ,因为它没有一个例子 ,所以很容易被忽略。 当我searchnetworking时,有很多很好的例子 ,当extends
是有效的时候引用swagger 1.2。
对于Swagger 2.0,我在github上通过这个谷歌组find了一个很好的例子
基于上面的资料,这里是YAML中一个简短有效的inheritance例子 :
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
定义,组合也能正常工作。
例如,基地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
它将被正确呈现为:
请注意, allOf
足以使其工作,并且不使用discriminator
字段。 这是好的,因为它工作,这是很重要的,因为我认为,工具将能够生成代码没有discriminator
字段。
这里所有的答案都很好,但我只是想添加一个关于组合与inheritance的小调。 根据Swagger / OpenAPI规范 ,为了实现组合 ,使用allOf
属性就足够了,正如@oblalex正确指出的那样 。 但是,要实现inheritance ,您需要使用allOf
和discriminator
,如@TomaszSętkowski所示 。
另外,我还在API Handyman发现了更多Swagger 组合和inheritance的例子。 它们是Arnaud Lauret 出色的Swagger / OpenAPI教程系列的一部分,我认为每个人都应该检查一下。
你已经共享的Swagger 2.0标准示例描述了一个合成关系,特别是它捕获了“是一种”超types/子types关系,但它本身并不是多态。
如果您可以引用Pet的基本定义作为input参数,那么可以selectCat或input一个Cat JSON对象作为input请求的值,并让Swagger UI可接受。
我无法得到这个直接工作。
我可以做的最好的工作是在基础对象(例如Pet)上设置additionalProperties为true,使用JSON指针引用指定Pet作为input模式,最后将我的Cat JSON值对象复制并粘贴到Swagger UI中。 由于附加属性允许Swagger UI生成有效的input请求有效载荷。