3 个版本
0.1.2 | 2024 年 3 月 10 日 |
---|---|
0.1.1 | 2024 年 3 月 7 日 |
0.1.0 | 2024 年 2 月 7 日 |
在 网络编程 中排名 621
每月下载量 98 次
75KB
2K SLoC
ArcISLE
-- Interface Specification Language。
其目标是提供一种轻量级的方式来描述软件中几乎任何类型的接口,并为分析和治理提供更高级的工具。
状态
项目处于早期开发阶段。目前,它可以解析根据以下规范创建的文档,并在不解析整个文档的情况下在不符合规范的地方发出错误。
最近计划是
- 添加类型声明验证。目前我们收集已声明的类型,但不会验证所有用法都严格遵循该声明并发出错误。
- 仍缺少缺失声明的精确定位,在完成之前添加会很好。
- 命令行界面。
- 检查较大文档的速度。到目前为止,它已经在一个非常小的 API 规范上进行了测试,需要更多的真实世界示例来定义是否需要进行优化。
- OpenAPI 与 ArcISLE 转换。
- 混合类型和路由声明
- 不同的路由版本
- 默认响应代码猜测
结构
所有规范仅使用 YAML 编写。这允许写出更少的内容,更快地完成,并且仍然有强大的工具来满足广泛的需求。JSON 存在一些不便的限制,例如几乎在所有地方都需要引号,这使得手动编写更困难。
主要部分如下
types
— 描述 API 中使用的对象列表。interfaces
— 描述 API 提供的端点。
默认情况下,建议不要维护包含所有描述的单个文档,而是开始将文件分解成两组:类型和接口。可以通过导入文档的子集来完成此操作
types:
_import: types.yml
导入还可以包括文件列表
_import:
- file1.yml
- file2.yml
- file3.yml
- file4.yml
文件的路径相对于请求导入的根文档解析。
类型
API 通常包含许多特定类型,例如用户、帖子或交易等。这些实体在定义接口时出现在许多地方。通过提前定义它们并重复使用,我们可以简化未来的工作流程。这就是类型的作用。
类型声明允许在 types
部分(或该部分包含的分离文件)中声明。要声明一个类型,指定其名称和字段集。每个字段都有自己的名称和类型,定义在分号之后。
user:
id: uuid
name: str
role: str
您还可以嵌套类型至3级(这个限制是人为设定的,旨在提高可读性)
settings:
version: str?
flags:
a: bool
b: bool
c: bool
类型可以在其他类型内部进行引用
post:
title: str
body: str
author: user
内置
规范支持一组默认类型:基本数据类型、容器和格式。它们用于满足基本需求,并允许构建自定义类型。
基本数据类型
我们正在处理的所有数据在最终分析后都有一些基本类型,其中大多数是最基本的,得到了支持
int
- 表示整数double
- 表示双精度数字bool
- 表示布尔值str
- Unicode字符串
容器
为了满足集合或嵌套JSON的需求,有两种容器类型
array[type]
或array
dict[key, value]
或dict
方括号用于定义内部元素,通过在其中指定类型,您可以表示期望的元素,例如整数数组或键为字符串且值为整数的字典。没有对可以使用的数据类型的限制。
无括号的表示法移除了元素的类型定义,这在某些情况下可能很有用,但通常不推荐使用。
特定格式
某些类型的数据被频繁使用,仅将其指定为字符串可能会丢失信息。为了改进这一点,规范提供了一些默认类型,这些类型被识别为常用类型。
timestamp
— 作为双精度数字,表示期望这个双精度数字是UNIX格式的时间。date_iso8601
— 作为字符串,表示和验证字段以确认ISO 8601日期标准。uuid
— 作为字符串,表示和验证字段以包含有效的UUID值。url
—
可选性
类型内的字段可能是必需的或可选的。为了简化声明,每个字段都有一个表示可选性的参数,该参数用 ?
符号表示。将其添加到字段类型末尾表示该字段是可选的,并且可以在该类型的实例中省略。
title: str
description: str?
connections: array[uuid]?
可选性 仅 指字段,而不是类型,这意味着指定例如 array[int?]
是 不 合法的语法。
JSON Schema
所有类型都按照设计与JSON Schema兼容。任何本规范的实现都必须提供一种方法从类型生成有效的模式。
接口
现在,每个REST API的核心实际上是端点,在这里被称为接口,因为它们是服务器和客户端之间的接口。接口的声明比类型的声明要复杂一些。每个接口的两个必填字段是 path
和 method
- path: news
method: get
路径可以使用花括号进行参数化
- path: users/{user_id}
如果可能的话,建议在参数名称中包含类型名称以提高可读性。比较以下版本
users/{id}/posts/{id}/comments/{id}
users/{user_id}/posts/{post_id}/comments/{comment_id}
不考虑嵌套决策的问题,第二个版本仅通过观察就更容易理解,因为我们清楚地知道每个参数代表什么。
其余选项取决于请求的详细信息,并遵循HTTP标准。
字段 | 必需 | 用途 | 限制 | 可能值 |
---|---|---|---|---|
查询 | 否 | 指定请求的查询参数。 | 仅允许在GET和HEAD请求中使用。 | 必须是一个有效的自定义类型。 |
正文 | 否 | 指定请求的正文。 | 允许在POST、PUT和PATCH请求中使用。 | 必须是一个有效的自定义类型。 |
body_type | 否 | 指定正文类型。 | 仅与存在正文时一起允许。 | 目前仅支持form-data值。 |
response | 否 | 指定请求的响应。 | 无限制。 | 响应中允许任何类型。 |
这足以指定考虑成功流程的基本端点要求,例如
types:
news_entry:
id: str
title: str
link: url
interfaces:
- path: news
method: get
query:
search: str?
response:
items: array[news_entry]
next_page_link: url?
- path: news
method: post
body:
title: str
link: url
response: news_entry
- path: news/{entry_id}
method: delete
不同的响应
一个高级场景是我们想为不同的案例定义自定义响应,如成功、失败、权限错误等。为了支持它,以下方式的response
字段支持可变内容
- path: news/{entry_id}
method: delete
response:
200: news_entry
4xx:
code: int
reason: str?
5xx:
message: str
501:
code: int
reason: str?
您可以在示例中指定具体的状态码,如200
或501
,或者状态码系列的模式,如4xx
和5xx
,并且您可以组合这两种风格。
默认情况下,如果response字段未指定任何代码,则假设为2xx
系列。
依赖关系
~2.2-8MB
~60K SLoC