























OpenAPI 规范(OAS),是定义一个标准的、与具体编程语言无关的RESTful API的规范。
OpenAPI 规范使得人类和计算机都能在"不接触任何程序源代码和文档、不监控网络通信"的情况下理解一个服务的作用。
简单来说,OpenAPI文档是一份机器可读的“说明书”,详细描述了你的 API 能做什么,包括:
核心价值:一旦你的 API 被定义在一个标准的 OpenAPI 文档中,整个 API 生命周期中的各种工具都可以基于此文档自动完成工作,极大地提高了效率和规范性。
用来定义或描述一个API的YAML(JSON)文档。OpenAPI 文档可以是单个文件也可以被拆分为多个文件,连接的部分由用户自行决定。固定字段:
|
字段 |
是否必须 |
描述 |
|
openapi |
是 |
OPENAPI版本号 |
|
info |
是 |
提供API相关的元数据,如API名称、描述、版本等 |
|
servers |
否 |
Server地址列表 |
|
paths |
是 |
定义API的所有请求路径及Action |
|
components |
否 |
提供可复用的组件定义,使用$ref引用 |
|
security |
否 |
声明API使用的安全机制 |
|
tags |
否 |
提供更多元数据的一系列标签。 |
|
externalDocs |
否 |
附加文档 |
文档的元数据,描述了 API 本身的基本信息。
openapi: 3.0.3 # OpenAPI版本
info:
title: Agents API # API的名称
description: 坐席相关接口
version: 1.0.0 # API的版本
contact:
name: API支持者
email: icc2.0@msxf.com
servers:
- url: https://test.example.com/v1 # API的基础地址
description: test环境服务器
- url: https://test1.example.com/v1 # AP 的基础地址
description: test1环境服务器
paths: # 接下来会定义所有端点
components: # 接下来会定义可重用的组件
tags:
- name: agents
description: "坐席相关接口"
- name: metrics
description: "指标相关接口"
paths- 路径OpenAPI文档核心,定义了 API 的所有可用URL以及每个URL支持的请求Action。
paths:
/agents:
get:
summary: 获取坐席列表
operationId: listAgents
tags:
- agents
parameters: # 参数定义
- name: limit
in: query
description: 返回结果的数量限制
schema:
type: integer
default: 10
responses: # 响应定义'200':description:成功返回坐席列表content:application/json:schema:type:arrayitems:$ref:'#/components/schemas/Agent'
post:
summary: 创建一个新坐席
operationId: createAgent
tags:
- agents
requestBody: # 请求体定义
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Agent' # 引用components定义的 Agent模型
responses: ... # 响应定义
/agents/{agentId}:
get:
summary: 通过ID获取坐席详情
operationId: getAgentById
parameters: # 包含路径参数 {agentId}-name:agentIdin:path# 参数位置:path, query, header, cookierequired:truedescription:坐席的IDschema:type:integer
responses: ...
components- 组件可以在 paths中通过 $ref来引用这些组件。
components:
schemas:
Agent:
type: object
required:
- id
- name
properties:
id:
type: integer
format: int64
name:
type: string
status:
type: string
Error:
type: object
required:
- code
- message
properties:
code:
type: integer
description: 错误代码
message:
type: string
description: 错误描述
如 200、400、401、403、404、500等通用响应结构,确保全站错误格式统一。
components:
responses:
BadRequest:
description: 400 Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
invalidParams:
summary: 参数验证失败
value:
code: 400
message: 请求参数无效
Unauthorized:
description: 401 Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
tokenExpired:
summary: Token无效
value:
code: 401
message: 访问令牌已过期
Forbidden:
description: 403 Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
insufficientPermissions:
summary: 权限不足
value:
code: 403
message: "没有操作权限"
依赖安装:
yarn add express swagger-ui-express swagger-jsdoc yamljs
yarn add --dev nodemon
通过express启动UI服务:
const express = require('express');
const swaggerUi = require('swagger-ui-express');
const YAML = require('yamljs');
const app = express();
const PORT = process.env.PORT || 3000;
// 加载YAML文件
const swaggerDocument = YAML.load('./swagger.yaml');
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument));
app.listen(PORT, () => {
console.log(`服务器运行在端口 ${PORT}`);
console.log(`Swagger文档: http://localhost:${PORT}/api-docs`);
});
本地Swagger UI:
GET: 查询/获取资源
POST: 创建资源
PUT: 全量更新资源
PATCH: 部分更新资源
DELETE: 删除资源
OpenAPI 规范使用 YAML 或 JSON 格式来描述 API,这两种格式都是机器可读的。这种标准化的描述方式不依赖于任何编程语言,使得不同的工具和系统能够基于同一份规范进行协作。
OpenAPI 规范文件可以自动生成交API 文档(如使用 Swagger UI)。文档不仅展示了 API 的URL、参数、请求和响应示例,还允许开发者直接在浏览器中尝试调用 API。
利用OpenAPI生成工具(如 Swagger Codegen、OpenAPI Generator),可以根据规范文件自动生成多种编程语言的客户端和服务器代码。前后端可以基于API文档MOCK调试,可以加速前后端的联调进程,并减少手动编写代码可能引入的错误。
OpenAPI 规范可以用于生成自动化测试用例,验证 API 的实现是否符合规范。可以基于 OpenAPI 规范自动生成测试用例,对 API 进行属性测试,确保 API 的健壮性。
OpenAPI 拥有庞大的生态系统,包括各种工具和库,支持从设计、生成、测试到监控的整个 API 生命周期。这些工具包括:
Schemathesis是一个基于属性测试(Property-based Testing)的API测试工具,专门用于测试符合OpenAPI/Swagger规范的Web API。
基于OpenAPI文档自动生成测试用例,覆盖API的所有端点和参数。
st run --checks all http://api.example.com/openapi.json
pip install schemathesis
# 验证安装
schemathesis --version
openapi: 3.0.3
info:
title: 坐席管理 API
description: 简单的坐席管理接口示例
version: 1.0.0
contact:
name: API 支持
email: support@example.com
servers:
- url: http://localhost:8000/api/v1
description: 开发服务器
- url: https://api.example.com/v1
description: 生产服务器
paths:
/agents:
get:
summary: 获取坐席列表
description: 获取系统中所有坐席的列表,支持分页和过滤
operationId: getAgents
tags:
- 坐席管理
parameters:
- name: page
in: query
description: 页码
required: false
schema:
type: integer
minimum: 1
default: 1
example: 1
- name: limit
in: query
description: 每页数量
required: false
schema:
type: integer
minimum: 1
maximum: 100
default: 20
example: 20
- name: active
in: query
description: 过滤活跃坐席
required: false
schema:
type: boolean
example: true
responses:
'200':
description: 成功获取坐席列表
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
example: true
data:
type: object
properties:
agents:
type: array
items:
$ref: '#/components/schemas/Agent'
pagination:
$ref: '#/components/schemas/Pagination'
message:
type: string
example: "坐席列表获取成功"
examples:
success:
summary: 成功响应示例
value:
success: true
data:
agents:
- id: 1
name: "张三"
email: "zhangsan@example.com"
age: 28
active: true
createdAt: "2024-01-15T10:30:00Z"
- id: 2
name: "李四"
email: "lisi@example.com"
age: 32
active: true
createdAt: "2024-01-16T14:20:00Z"
pagination:
page: 1
limit: 20
total: 2
pages: 1
message: "坐席列表获取成功"
'400':
description: 请求参数错误
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
invalid-params:
summary: 参数错误示例
value:
success: false
error:
code: "INVALID_PARAMS"
message: "参数验证失败"
details:
- field: "limit"
message: "必须小于或等于100"
message: "请求参数无效"
'500':
description: 服务器内部错误
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
server-error:
summary: 服务器错误示例
value:
success: false
error:
code: "INTERNAL_ERROR"
message: "服务器内部错误"
message: "系统繁忙,请稍后重试"
components:
schemas:
Agent:
type: object
required:
- id
- name
- email
properties:
id:
type: integer
format: int64
description: 坐席唯一标识
example: 1
name:
type: string
description: 坐席姓名
minLength: 1
maxLength: 50
example: "张三"
email:
type: string
format: email
description: 坐席邮箱
example: "agent@example.com"
age:
type: integer
minimum: 0
maximum: 150
description: 坐席年龄
example: 28
active:
type: boolean
description: 是否活跃
default: true
example: true
createdAt:
type: string
format: date-time
description: 创建时间
example: "2024-01-15T10:30:00Z"
updatedAt:
type: string
format: date-time
description: 更新时间
example: "2024-01-20T08:15:00Z"
Pagination:
type: object
properties:
page:
type: integer
description: 当前页码
example: 1
limit:
type: integer
description: 每页数量
example: 20
total:
type: integer
description: 总记录数
example: 150
pages:
type: integer
description: 总页数
example: 8
Error:
type: object
properties:
success:
type: boolean
example: false
error:
type: object
properties:
code:
type: string
description: 错误代码
example: "VALIDATION_ERROR"
message:
type: string
description: 错误信息
example: "参数验证失败"
details:
type: array
items:
type: object
properties:
field:
type: string
example: "email"
message:
type: string
example: "必须是有效的邮箱格式"
message:
type: string
description: 坐席友好的错误信息
example: "请求参数无效"
securitySchemes:
BearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
description: JWT token认证
准备nodejs环境,安装prism
yarn global add @stoplight/prism-cli
# 动态模拟接口返回
prism mock openapi.yaml --dynamic
服务启动后检查API正常返回
命令行执行:
schemathesis run openapi.yaml --url=http://127.0.0.1
执行结果:
测试报告生成yaml格式:
schemathesis run openapi.yaml --url=http://127.0.0.1 --report vcr --report-vcr-path ./custom-vcr.yaml
集成示例:
import schemathesis
schema = schemathesis.openapi.from_path("./openapi.yaml")
@schema.parametrize()
def test_api_code(case):
print(case)
response = case.call(url="http://127.0.0.1")
assert response.status_code is not None
assert response.status_code != 500
@schema.parametrize()
def test_api_response(case):
print(case)
case.call_and_validate(url="http://127.0.0.1")
测试报告:
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。