如何将 swagger 2.0 JSON 文件分解为多个模块
Posted
技术标签:
【中文标题】如何将 swagger 2.0 JSON 文件分解为多个模块【英文标题】:How to break swagger 2.0 JSON file into multiple modules 【发布时间】:2015-01-11 02:07:47 【问题描述】:我正在尝试将我的 API 文档分解为多个可以独立编辑的 JSON 文件。我能找到的所有示例都使用 Swagger 1.2 模式,它有一个“api”: 对象来分解它。 2.0 模式 (http://json.schemastore.org/swagger-2.0) 似乎缺少这点。所定义的只是一个单一的“路径”数组,它将所有 API 端点捆绑到该单一数组中。这在 swagger-ui 中的效果是有一个单一的“默认”类别,所有内容都被捆绑到其中,我无法告诉将其拆分。
TLDR:如何从 swagger 2.0 架构中的路径拆分操作
"swagger": "2.0",
"info":
"description": "My API",
"version": "1.0.0",
"title": "My API",
"termsOfService": "http://www.domain.com",
"contact":
"name": "support@domain.com"
,
"basePath": "/",
"schemes": [
"http"
],
"paths":
"Authorization/LoginAPI":
"post":
"summary": "Authenticates you to the system and produces a session token that will be used for future calls",
"description": "",
"operationId": "LoginAPI",
"consumes": [
"application/x-www-form-urlencoded"
],
"produces": [
"application/json"
],
"parameters": [
"in": "formData",
"name": "UserName",
"description": "Login Username",
"required": true,
"type": "string"
,
"in": "formData",
"name": "Password",
"description": "Password",
"required": true,
"type": "string"
],
"responses":
"200":
"description": "API Response with session ID if login is allowed",
"schema":
"$ref": "#/definitions/Authorization"
【问题讨论】:
【参考方案1】:你实际上是在一个问题中提出了几个问题,我会尽力回答所有问题。
在 Swagger 1.2 和之前的版本中,文件拆分是强制性的和人为的。它旨在作为一种对操作进行分组的方式,而 Swagger 2.0 提供了这样做的替代方法(稍后会详细介绍)。
Swagger 2.0 确实是一个单独的文件,它允许在任何使用 $ref
的地方使用外部文件。您不能将单个服务拆分为多个文件并将它们组合为一个文件,但您可以在外部为特定路径指定操作(同样,使用$ref
属性)。
我们目前正在最终确定将多个微服务整理到一个集合中的能力,但最终,每个微服务仍将是一个文件。
如前所述,Swagger 2.0 中的操作分组发生了变化,“资源”的概念不再存在。相反,可以为每个操作分配标签(带有"tags"
属性)。 tags
是一个值数组,与以前的版本不同,如果需要,每个操作可以存在于多个标签下。在 Swagger-UI 中,所有未定义标签的操作都将在 default
标签下结束,这是您所看到的行为。顶层对象还有一个额外的 tags
属性,允许您向标签添加描述并设置它们的顺序,但不强制包含它。
最后一点,我不知道 Swagger 2.0 的 json-schema 是如何以http://json.schemastore.org/swagger-2.0 结尾的,但它肯定不是最新的。最新的架构可以在这里找到 - http://swagger.io/v2/schema.json - 它仍在开发中。请记住,事实的来源是规范 (https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md) 而不是架构,因此如果发生冲突,规范会“获胜”。
编辑:
我们刚刚发布了参考指南。它可能对某些用例有所帮助 - https://github.com/OAI/OpenAPI-Specification/blob/master/guidelines/v2.0/REUSE.md
【讨论】:
所以如果我想为每个标签创建单独的文件,这可能吗?我可以看到使用 $ref 将所有资源(例如)放入一个单独的文件中,但是您将如何拆分“路径”数组? 你不能那样做。同样,微服务解决方案很快就会出现,但这并不一定意味着 tag==micro-service。 你能在不同的文件中定义路径和模型吗? swagger 2.0 中的例子? 对于模型,您可以$ref
外部定义。对于路径,目前有一个解决方案,但它有问题,所以最好不要现在使用它。
关注github.com/swagger-api/swagger-core/wiki/…和github.com/swagger-api/swagger-core/wiki/1.3--1.5-Migration。【参考方案2】:
我已经在this blog post 中写过这个。您基本上可以使用 JSON Refs 库将所有 Swagger 小文件解析为一个大文件并在工具中使用。
【讨论】:
博文中的一些(大多数?)示例是错误的。$ref
不允许无处不在,它只允许在有限的地方 - Specification 明确声明关键字的值可以是“参考对象”。例如,info: $ref: ./info/index.yaml
无效,其他一些示例也是如此。
@Helen 我的工具openapi-preprocessor 是你需要的。【参考方案3】:
如果 JSON ref 不适合您,编写您自己的连接器可能会很有用。好吧,您实际上可以使用已经存在的东西,而不是自己编写。任何模板引擎都可以。就我而言,Handlebars 非常有用(因为 Handlebars 实际上保留了缩进,这对于 Yaml 文件来说是完美的,因为它们区分大小写)。
然后你就可以在 Node 中有一个构建脚本了:
'use strict';
var hbs = require('handlebars');
var fs = require('fs');
var dir = __dirname + '/your_api_dir';
var files = fs.readdirSync(dir);
files.forEach((fileName) =>
var raw = fs.readFileSync(dir + '/' + fileName, 'utf8');
hbs.registerPartial(file, raw);
);
var index = fs.readFileSync(dir + '/index.yaml');
var out = hbs.compile(index.toString());
阅读有关问题的更多信息on my blog。
【讨论】:
为什么要减掉这个回复?提到了 JSON refs,其他一切都是可行的解决方法(虽然我不太喜欢它,但对于某些用例,它可能被证明是最简单的方法)。 博客链接失效了,Oleg 也有一段时间没有上来了。这是 Wayback Machine 博客页面快照的链接:web.archive.org/web/20160209064025/http://olegberman.com/…【参考方案4】:请注意,RepreZen API Studio 现在通过此处讨论的$ref
语法支持多文件 Swagger/Open API 项目。因此,您可以将大型 Swagger 项目分解为模块,以实现重用和团队协作。然后,当您需要将 API 模型带出设计/开发环境时,您可以使用内置的 Swagger 规范化器来创建单个整合的 Swagger 文件。
注意:为了全面披露,我是 RepreZen 的产品经理。上周我偶然发现了这个帖子,并认为我会参与进来。
【讨论】:
【参考方案5】:我也在尝试解决这个问题,Swagger Google group 中有一些有用的信息。看起来共识是,只要 $ref 指向绝对 URL,您就可以将定义分成单独的文件。此处示例:
https://github.com/swagger-api/swagger-spec/blob/master/fixtures/v2.0/json/resources/resourceWithLinkedDefinitions.json#L32
https://github.com/swagger-api/swagger-spec/blob/master/fixtures/v2.0/json/resources/resourceWithLinkedDefinitions_part1.json
【讨论】:
【参考方案6】:如果json不适合你bis,你也可以使用node.js,你也可以使用module.exports
我在模块中有我的定义,我可以在一个模块中要求一个模块:
const params = require(./parameters);
module.exports =
description: 'Articles',
find:
description: 'Some description of the method',
summary: 'Some summary',
parameters: [
params.id,
params.limit,
...
【讨论】:
【参考方案7】:我编写了一个 Swagger/OpenAPI 预处理器来简化规范的编写。
https://github.com/dolmen-go/openapi-preprocessor/
特别是它支持 $ref
指向外部文件并允许将您的规范编辑为多个文件,但生成单个文件以最大程度地与将使用它的工具兼容。
【讨论】:
【参考方案8】:Swagger JSON 可以通过为每个模块创建文档来拆分为多个模块,如下所示:
`
@Bean
public Docket module1()
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.example.module1"))
.paths(PathSelectors.any())
.build()
.groupName("module1")
.apiInfo(apiInfo());
`
每个模块的 URL 将创建为 http://localhost:xxxx/context-path/v2/api-docs?group=module1
【讨论】:
以上是关于如何将 swagger 2.0 JSON 文件分解为多个模块的主要内容,如果未能解决你的问题,请参考以下文章
是否可以在 ASP .NET Core 中使用 Swashbuckle 在 Swagger 2.0 和 Open API 3 格式中公开相同的 Swagger JSON?