使用 OAS(OpenAPI标准)来描述 Web API

无论哪种类型的Web API, 都可能需要给其他开发者使用. 所以API的开发者体验是很重要的. API的开发者体验, 简写为 API DX (Developer Experience). 它包含很多东西, 例如如何使用API, 文档, 技术支持等等, 但是最重要的还是API的设计. 如果 API 设计的不好, 那么使用该API构建的软件就需要增加在时间,人力,金钱等方面的投入. 有时候API会被错用, 甚至带来毁灭性后果. 最后抱怨该API等用户越来越多, 慢慢的, 客户就会停止使用该API. 

 

API的目的是让人们可以简单的使用它来达到自己的目的. 目前行业内有很多API风格, 例如: REST, gRPC, GraphQL, SOAP, RPC等等. 但是每个风格都遵循一些基本的设计原则. 

 

用户就是上帝, 为用户设计API 

和构建任何东西一样, 你需要一个计划, 你需要在真正做之前来决定你想要的是什么. API 设计也是一样的. 

API 并不是用来盲目的暴露一些数据或业务处理能力. 它就像我们每天使用的任何形式的接口一样, 例如微波炉的操作按钮, 是来帮助用户完成他们的目标的. 所以需要从用户的视角来决定一个API的设计目标. 在整个设计过程中, 必须牢记以用户的视角去设计, 如果以开发者的角度去设计, 那么问题就大了. 

 

如果以开发者的视角去设计的API, 那么通常的后果是开发出的API会很注重功能实现的过程和原理, 而不是用户如何能简单平滑的使用这个API来达到他们的目的. 所以一定要注重用户的需求, 而不要让内部实现细节, 原理什么的来骚扰用户. 最后再次强调, 要设计出让用户容易理解和容易使用的API. 

所以 API 就是用户看到的, 它表示出用户能使用它做什么. API 的实现细节, 也就是如果完成的该功能的细节, 需要对用户隐藏. 

 

识别 API 的目标 

记住首先考虑用户的感受之后, 下面就需要考虑用户能拿它来做什么了, 也就是识别API的目标.  

识别 API 的目标, 最基本的要对以下方面有深刻, 精准的认识: 

  1. Who, 谁可以使用这个API? 

  2. What, 用户拿这个API能做什么事?  

  3. How, 用户如何做这件事? 

  4. What need, 用户想要做这件事的话还需要什么? 

  5. What return, 用户会得到什么? 

 

1.就是指API的用户, 4,5分别表示输入输出.  

 

针对2, 3解释一下 

通常针对2.What(用户拿API能做什么)可以导致(分解)多个3.How(多个步骤), 这样的话每个步骤就是一个API的目标. 

比如说, 用户想去淘宝买一个商品, 那么怎么买? 首先需要把商品添加到购物车, 然后再结账. 那么这个API就应该有两个目标: 添加商品到购物车, 以及 结账. 

如果不这样分解到话, 通常设计出的API会缺失一些目标. 

 

针对1, 也解释一下 

首先应该识别出不同种类的用户, 这里的用户可能是人, 也可能是其他的程序. 通常通过检查输入和输出就可以识别出用户. 

 

总结一下就6个方面: 

  • 用户 

  • 能做什么 

  • 如何做 - 分解步骤 

  • 输入 

  • 输出 

  • 目标 

 

避免从开发者角度设计API 

这部分包含几个方面. 包括: 

  • 开发者所在公司的组织结构(参考康威定律) 

  • 数据, 例如数据使用了开发者所在公司内部的一些专有术语, 或者干脆把内部数据库模型暴露了出来. 

  • 不要暴露实现细节, 避免受到业务逻辑实现细节的影响 

  • 避免受到软件架构的影响, 比如说在开发者公司内部查询产品名称和产品价格是两个API, 那么给用户使用的API必须整合一下, 不能让用户分两步查询. 

 

最重要的还是要时刻牢记, 你所设计的这些东西都是用户真正需要的吗? 

 

 

下面切入正题: 

使用API描述格式来描述API 

这里我以RESTful风格的API为例. 想要了解使用ASP.NET Core 3.x 构建 RESTful API, 这里有一个教程(但是还没讲完) https://www.bilibili.com/video/av77957694/

 

很多人使用Excel或者纸和笔来进行API的设计工作. 但是如果想要在设计阶段精准描述一个API, 尤其是它的数据, 那么最好使用一个结构化的工具, 例如API描述格式.  

API描述格式会为API提供一个标准化的描述, 并且它很像代码. 它的优势主要有: 

  • 有助于在项目团队中共享设计 

  • 了解这种格式的人或者工具可以很简单的理解它. 

 

针对REST而言, OpenAPI Specification(OAS) 就是一个非常流行API描述格式规范. 

 

OAS 

API描述格式是一种数据格式, 它的目标就是描述API. 

而OAS (OpenAPI Specification)是一个与编程语言无关的REST API描述格式. 它是由 OAI (OpenAPI Initiative) 所提倡的. OAI 是Linux基金会下面的一个组织, 专注于提供与供应商无关的描述格式. 而OAS则是社区驱动的一种格式, 任何人都可以做贡献. 

 

OAS vs Swagger 

OAS 原来叫 Swagger Specification, 2015年11月这个格式被贡献给了OAI, 并在2016年1月更名为 OpenAPI Specification. Swagger 规范最后的2.0版本就变成了 OpenAPI 2.0. 目前最新的OAS 应该是3.0大版本 

 

YAML 

OAS文档可以使用YAML或JSON格式, 我使用YAML. 

 

像写代码一样描述API 

OAS文档就是一个文本文件, 可以纳入版本控制系统 ,例如 Git等. 所以在设计迭代的时候很容易进行版本管理和变化追踪. 

 

编辑器 

OAS有一个在线的专用编辑器: http://editor.swagger.io/ 

左边是代码编辑区域, 右边是渲染结果. 

 

但是我更习惯于本地编辑器, 我使用VSCode, 并安装 Swagger Viewer 和 openapi-lint 两个插件. 

共享API描述API进行文档记录 

OAS文档可以用来生成API对引用文档, 这个引用文档可以展示出所有可用的资源以及相应的操作. 通常我会使用Swagger UI, 它就是上图右侧的部分. 

 

生成代码 

使用API描述格式进行描述的API, 其代码也可以部分生成. 通常是一个代码骨架. 

 

什么时候使用API描述格式 

肯定是在设计接口如何表达API目标和概念, 以及数据的时候. 

 

使用OAS来描述REST API的资源以及Action 

创建OAS文档 

建立一个products.yaml文件.  

然后在里面输入 api 或 open等字符串, 会出现两个提示选项: 

先选择下面那个选项, 其结果是: 

  • 第1行是Open API的版本 

  • 第4行 info 的 version 是指API的版本, 而info这个版本必须使用双引号括起来, 否则OAS解析器会把它当成数字, 从而导致文档验证失败(因为它的类型应该是字符串). 

  • 第5行 paths, paths属性应该包含该API可用的资源. 这里面使用 {} 仅仅是为了让文档验证通过, 因为我目前还没有写什么内容. 在YAML里, {} 表示一个空的对象, 而非空的对象则不需要这对大括号. 

 

描述资源 

为了描述products这个资源, 就需要填写paths属性: 

这里description属性不是强制的, 但是它可以用来描述该资源. 

 

描述资源的操作 

OAS文档里描述的资源肯定包含一些操作, 否则文档就不合理. 

看代码: 

我为/products这个资源添加了一个GET Action (get属性), 然后我对这个get也进行了描述. 

summary相当于是对这个Action的一个概括性描述, 而description则能提供更详细的描述信息.  

这里description是支持多行文本的, 但是在YAML里面要想支持多行文本, 那么string属性必须以 | 管道符 开头. 

注意, 这里第1行 openapi下面的波浪线表示文档验证失败. 

 

在OAS文档里, 一个操作必须在responses属性里提供至少一个响应: 

一个Action可能有多种响应结果, 每种可能的响应结果都要在responses属性中描述. 

每个响应都以状态码进行标识, 并且必须包含一个description属性. 

注意: 状态码数字必须用双引号括起来, 因为它的类型本应该是字符串, 而这里的200是一个数字. 

 

下面我再添加一个POST Action: 

这里还是针对 /products 这个资源, 我就不过多解释了. 

 

使用OpenAPI  JSON Schema 来描述 API 的数据 

OAS 依赖于 JSON Schema 标准来对所有的数据(查询参数, body 参数, 响应body等)进行描述. 

 

注意, OAS 使用的其实是JSON Schema的一个子集, 并不包含所有的 JSON Schema 特性, 并且还添加了一些 OAS 独有的特性到这个子集里. 
 

描述查询参数 

如果我们的get操作里需要一些查询参数(查询字符串, Query String), 那么可以使用 parameters 这个属性:

这里 parameters属性是一个集合或数组, 每个集合元素使用 - 开头. 

为了描述一个参数, 至少需要name, in 和 schema 三个属性. 在本例中, 还包含 required 和 description 两个可选的属性. 

  • in表示参数的位置, 这里值为query, 表述它是查询字符串(Query String, 例如 api/products?searchTerm=xxx).  

  • required 为 false 表示不是必填参数. required是可选的, 如果没有写的话, 那么它的值就是false. 但是最好还是写上required属性. 

  • 它的数据结构使用schema属性来表示, 这里就是一个简单的字符串类型. 但是它其实是一个JSON schema, 所以它可以是复杂的对象类型. 

  • description属性也是可选的, 但是最好还是写上吧, 有个描述更好. 

 

使用JSON Schema来描述数据 

假设一个对象有三个属性: 编号(string), 名称(string), 价格(number). 那么使用JSON Schema来描述它就应该是这样的: 

还没完, 我还必须指出属性是否是必填的, 然后我再加上一个remark属性, 它不是必填的: 

JSON Schema 通过 required 这个集合属性来表示哪些属性是必填的. 

 

此外, 我还可以在这里添加 description 和 example (示例)属性: 

此外 JSON Schema 还支持 对象属性类型: 

JSON Schema 的东西比较多, 具体可以查找一下官方文档. 

 

描述响应 

在OAS文档里, 操作响应返回的body里的数据是用content属性来表示: 

这里需要注意的就是该操作的结果是产品的数组, 所以类型是array, 而array 的 items属性就包含着数组元素的schema. 

 

描述 body 参数 

像 POST 这样的 Action, 它的参数是在请求的body里面. 

body参数需要使用 requestBody属性描述, 看代码: 

这个 body 参数的内容也是使用 JSON Schema来描述的. 

 

描述路由参数 

像 api/products/{productId} 这样的URI里, productId就是一个路由/路径参数. 

它可以这样描述: 

这里面name的值必须和 {} 里面的值一样. 

in 的值为 path, 表示是路径参数. 

路径参数是必填的, 所以 required 为 true. 不然解析器会报错. 

 

可复用组件 

OAS允许使用可复用的组件, 例如 schema, 参数, 响应等等, 使用它们的时候添加个引用就行. 

 

假设针对 /products 这个资源一共有两个操作: 一个是返回一组产品, 另一个返回单个产品. 这时候返回产品的JSON Schema就可以使用一个可复用的schema. 

可复用的组件要放在components区域, 它是OAS文档的一个根级属性. 看例子: 

这里面, 可复用的schema被定义在schemas属性里, 每个可重用的schema的名字就是schemas的值, 这里就是product. 它下就包含着可重用的组件: 一个 JSON Schema. 

 

引用定义好的schema 

引用定义好的schema需要使用到JSON引用. JSON引用这个属性的名字是$ref, 它的值是一个URL. 这个URL可指向本文档内部甚至外部的组件. 这里我只引用文档内部的组件. 

而针对那个 get Action的返回结果(数组类型), 需要把JSON引用放在 array 的 items属性里. 

 

可复用参数 

直接看代码: 

和可复用schema类似, 可复用参数也放在components下面, 它所在的区域是 parameters. 其引用方式也类似, 就不过多介绍了. 

 

除了在Action级别引用可复用参数, 在资源这个级别也可以这样做: 

预览 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/312196.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

dedemodule.class.php,DEDECMS5.7模块/模块管理列表显示空白问题解决方法

DEDECMS5.7模块/模块管理列表显示空白(站长基地配图)今天站长基地升级至dedecms最新版本,进入后台意外的发现,模块/模块管理一片空白,但有没有及时备份,于是赶紧去网上找寻解决办法,经过整理,大致有以下几种…

dotNET Core 中怎样操作AD(续1)

在之前的文章《dotNET Core 中怎样操作 AD?》中主要以AD的数据同步到数据库的场景来描述了在 dotNetCore 中怎样操作AD,本文将继续介绍一些在 dotNetCore 中操作 AD 的其他常用操作。环境dotNET Core:3.0Novell.Directory.Ldap.NETStandard2_…

【Magicodes.IE 2.0.0-beta1版本发布】已支持数据表格、列筛选器和Sheet拆分

为了更好的完善Magicodes.IE,春节期间我们会进行一次大的重构。由于精力有限,急缺文档和翻译(将文档翻译为英文文档)支持,诚邀各位加入。同时在功能方便也做了相关规划,有兴趣的朋友可以参与提交PR。https:…

Mbp,一个用于学习.net core的开发框架

Mbp(https://github.com/mbpframework/Mbp)是一个.net core 3的企业级web开发框架,是我个人用于学习.net core而发起的一个开源项目.这个借鉴了国外优秀开源项目abp vnext,及国内优秀开源框架Osharp的一些思想和实现.欢迎各路开发爱好者加入这个项目,一起学习,一起玩耍,共同成长…

什么?原来C#还有这两个关键字

系列介绍简介【五分钟的dotnet】是一个利用您的碎片化时间来学习和丰富.net知识的博文系列。它所包含了.net体系中可能会涉及到的方方面面,比如C#的小细节,AspnetCore,微服务中的.net知识等等。场景您可以在下班坐地铁的时候,拿出…

蓝桥杯2015初赛-三羊献瑞-枚举

题目描述 观察下面的加法算式: 其中,相同的汉字代表相同的数字,不同的汉字代表不同的数字。 请你填写“三羊献瑞”所代表的4位数字(答案唯一),不要填写任何多余内容。 输出 请你填写“三羊献瑞”所代表…

如何利用Serilog的RequestLogging来精简ASP.NET Core的日志输出

这是该系列的第一篇文章:在ASP.NET Core 3.0中使用Serilog.AspNetCore。第1部分-使用Serilog RequestLogging来简化ASP.NET Core的日志输出(本篇文章)第2部分-使用Serilog记录所选的端点名称[敬请期待]第3部分-使用Serilog.AspNetCore记录MVC…

net下的高性能轻量化半自动orm+linq的《SqlBatis》

一、项目介绍该项目内置单表linq操作,xml动态sql解析,词法分析,类型映射等功能。SqlMapper,用来处理sql与数据库操作,它设计的目标是支持mysql,sqlserver,sqllite,pgsql等.TypeMapper用于完成将数据库的字段类型映射到C#类型&…

如何快速融入团队(六)

作者:邹溪源,长沙资深互联网从业者,架构师社区特邀嘉宾!一我总是在记忆深处探访那些拥有高效率团队的一切特征,并试图从纷繁复杂的记忆尘埃中找出一些共性,庆幸我已经习惯于通过阅读和思考来解读这些内容&a…

临近年关,修复ASP.NET Core因浏览器内核版本引发的单点登录故障

临近年关,咨询师提出360、搜狗急速浏览器无法单点登录到公司核心产品WD: 重定向过多。现象经过测试, 出现单点登陆故障的是搜狗、360等双核浏览器(默认使用Chrome内核), 较新式的Edge、Chrome、Firefox均未出现此障碍。Developer tool监测不到…

Asp.Net Core 已支持 gRPC-Web !!

grpc-dotnet 项目在 PR #695 完成了 ASP.NET Core 服务与 .NET Core gRPC 客户端的 gRPC-Web 实现。虽然目前还是实验性项目,但是并不阻碍我们为之兴奋。下面我们来看看如何使用。gRPC-Web 简介gRPC-Web 允许从浏览器应用程序使用 gRPC,gRPC-Web 支持在新…

蓝桥杯2017初赛-打印大X-找规律

题目描述 小明希望用星号拼凑,打印出一个大X,他要求能够控制笔画的宽度和整个字的高度。 为了便于比对空格,所有的空白位置都以句点符来代替。 要求输入两个整数m n,表示笔的宽度,X的高度。 输入 输入存在多组数据 …

蓝桥杯2015决赛-方格填数-枚举 or dfs

题目描述 在2行5列的格子中填入1到10的数字。 要求:相邻的格子中的数,右边的大于左边的,下边的大于上边的。 如下图所示的2种,就是合格的填法。 请你计算一共有多少种可能的方案。 输出 请输出该整数,不要输出任何多…

【实战 Ids4】║ 在Swagger中调试认证授权中心

回家的路上照顾好自己哟~大家好,老张已经顺利到家啦,闲的无事写两篇文章冒个泡吧,其实写的内容都是群友提出来的问题,简单的我会在群里直接提供思路,麻烦的我就写个文章说明一下吧,也是自己的一个记录作用&…

linux 集群 java,Linux Tomcat 集群 利用记实1--搭建javaWeb运行情况

前段时候一向在搞linux,有很多多少工具只曩昔没有做过。影象不是那么深刻,此刻把历程记实下来,以备今后盘问。一:起首说一下我们的计划, 一共有六台办事器,此中两台安置Oracle 10g做数据库集群(这个不在这篇…

在 Blazor WebAssembly 中使用 gRPC-Web

对于单页面应用程序,gRPC-Web 是 JSON-over-HTTP 的一种方便、高性能的替代方案。如果你已经了解关于 gRPC 和 gRPC-Web 的一切,你可以跳到 添加 gRPC 服务到一个Blazor WebAssembly 应用程序 一节。如果你只是想要一些简单的 Blazor WebAssembly gRPC-…

【新书推荐】《ASP.NET Core微服务实战:在云环境中开发、测试和部署跨平台服务》 带你走近微服务开发...

《ASP.NET Core 微服务实战》译者序:https://blog.jijiechen.com/post/aspnetcore-microservices-preface-by-translator/“微服务”的概念在 2014 年正式提出之后,越来越多的团队开始用它来设计自己的业务系统,各种微服务框架和开发过程管理…

.NET Core验证ASP.NET密码

.NET Core验证ASP.NET密码随着 .NETCore的持续更新和完善,越来越多的机构已经选择或者升级为 .NETCore。但由于技术不完全相同,不可能所有应用/数据库都能无缝迁移,因此 ASP.NETCore和传统 ASP.NET之间多少会存在一些挑战,需要更多…

linux下I2C驱动发送IO时序,I2C驱动情景分析——怎样控制I2C时序

内核版本:linux-3.4.2源程序: linux-3.4.2\drivers\i2c\busses\I2c-s3c2410.c这次要解决的问题是:如何配置soc的I2C模块,输出想要的时序波形?关于Linux里I2C驱动的架构,在转载的文章讲得相当透彻(《linu…

蓝桥杯2017初赛-外星日历-数论

题目描述 某星系深处发现了文明遗迹。他们的计数也是用十进制。 他们的文明也有日历。日历只有天数,没有年、月的概念。 有趣的是,他们也使用了类似“星期”的概念,只不过他们的一个星期包含了9天,为了方便,这里分别记…