问题:如何跨文件拆分swagger定义?该领域有哪些可能性?问题详情如下:
我确实有RAML的经验,我的工作是,例如:
/settings:
description: |
This resource defines application & components configuration
get:
is: [ includingCustomHeaders ]
description: |
Fetch entire configuration
responses:
200:
body:
example: !include samples/settings.json
schema: !include schemas/settings.json
最后两行在这里很重要 - 带有!include <filepath>
的内容 - 在RAML中我可以将我的整个合同拆分成许多文件,这些文件只是由RAML解析器动态包含(并且RAML解析器被所有基础工具使用)在RAML)。
我的好处是:
据我所知,swagger支持$ref
关键字,允许加载外部文件。但是这些文件是通过HTTP / AJAX获取的还是只是本地文件?
是否支持整个规范,或者只是支持它的一些工具和一些不支持的工具?
我发现here是swagger的输入必须是一个文件。这对大型项目来说非常不方便:
或者,换句话说,在分割文件方面,我可以用闪光灯来实现同样的目标吗?
答案 0 :(得分:6)
The specification允许多个位置的引用,但不无处不在。这些引用的解析取决于规范的托管位置 - 以及您尝试做的事情。
对于像渲染动态用户界面之类的东西,那么是的,你需要最终将整个定义加载到单个对象&#34;这可能是由许多文件组成的。如果执行代码生成,则可以直接从文件系统加载定义。但最终有一些摇摆解析器在进行分辨率,这在Swagger中比其他定义格式更细粒度和可控制。
在您的情况下,您将使用指向架构引用的JSON指针:
responses:
200:
description: the response
schema:
通过本地参考
$ref: '#/definitions/myModel'
通过绝对参考:
$ref: 'http://path/to/your/resource'
通过相对引用,相对于加载此文档的位置&#39;
$ref: 'resource.json#/myModel
通过内联定义
type: object
properties:
id:
type: string
答案 1 :(得分:1)
有关如何在多个文件中拆分Swagger文档的详细信息,请参阅this answer。这是使用JSON完成的,但同样的概念可以应用于RAML。
编辑:在此处添加链接内容
Swagger JSON的基本结构应如下所示:
{
"swagger": "2.0",
"info": {
"title": "",
"version": "version number here"
},
"basePath": "/",
"host": "host goes here",
"schemes": [
"http"
],
"produces": [
"application/json"
],
"paths": {},
"definitions": {}
}
paths
和definitions
是您需要插入API支持的路径以及描述响应对象的模型定义的地方。您可以动态填充这些对象。这样做的一种方法是为每个实体的路径和模型分别创建一个文件。
假设您的API中的一个对象是“汽车”。
路径:
{
"paths": {
"/cars": {
"get": {
"tags": [
"Car"
],
"summary": "Get all cars",
"description": "Returns all of the cars.",
"responses": {
"200": {
"description": "An array of cars",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/car"
}
}
},
"404": {
"description": "error fetching cars",
"schema": {
"$ref": "#/definitions/error"
}
}
}
}
}
}
型号:
{
"car": {
"properties": {
"_id": {
"type": "string",
"description": "car unique identifier"
},
"make": {
"type": "string",
"description": "Make of the car"
},
"model":{
"type": "string",
"description": "Model of the car."
}
}
}
}
然后,您可以将每个文件放在自己的文件中。启动服务器时,可以获取这两个JSON对象,并将它们附加到基本swagger对象中的相应对象(paths
或definitions
),并将该基础对象作为Swagger JSON对象提供
您还可以通过在服务器启动时仅执行一次附加来进一步优化此功能(因为在服务器运行时API文档不会更改)。然后,当命中“serve Swagger docs”端点时,您可以返回在服务器启动时创建的缓存Swagger JSON对象。
可以通过向/api-docs
发送请求来截取“服务Swagger文档”端点,如下所示:
app.get('/api-docs', function(req, res) {
// return the created Swagger JSON object here
});
答案 2 :(得分:1)
当我使用引用分割OpenAPI V3文件时,我尝试避免使用袜子抽屉反模式,而是对YAML文件使用功能分组。
我也这样做,以便每个YAML文件本身都是有效的OpenAPI V3规范。
我从openapi.yaml
文件开始。
openapi: 3.0.3
info:
title: MyAPI
description: |
This is the public API for my stuff.
version: "3"
tags:
# NOTE: the name is needed as the info block uses `title` rather than name
- name: Authentication
$ref: 'authn.yaml#/info'
paths:
# NOTE: here are the references to the other OpenAPI files
# from the path. Note because OpenAPI requires paths to
# start with `/` and that is already used as a separator
# replace the `/` with `%2F` for the path reference.
'/authn/start':
$ref: 'authn.yaml#/paths/%2Fstart'
然后在功能组中:
openapi: 3.0.3
info:
title: Authentication
description: |
This is the authentication module.
version: "3"
paths:
# NOTE: don't include the `/authn` prefix here that top level grouping is
# in the `openapi.yaml` file.
'/start':
get:
responses:
"200":
description: OK
通过这种分离,您可以独立地将每个文件或整个API作为一个组进行测试。
在某些地方您可能会重复自己,但是这样做可以限制使用“公共”库时破坏对其他API端点所做的更改的机会。
但是,您仍应具有一些通用的定义库,例如:
此方法有一个局限性,那就是“鉴别符”(尽管这可能是ReDoc的问题,但是如果您的类型在openapi.yaml
ReDoc之外具有鉴别符,则无法正确呈现。
答案 3 :(得分:0)
你可以使用$ ref但没有很好的灵活性,我建议你使用像'Yamlinc'这样的外部工具处理YAML,它使用'$ include'标签将多个文件混合成一个。