ITPub博客

首页 > 云计算 > 公有云实践 > 基于OAS设计可扩展OpenAPI

基于OAS设计可扩展OpenAPI

原创 公有云实践 作者:PaaS小魔仙 时间:2018-10-18 19:40:45 0 删除 编辑

随着互联网行业的兴起,开发模式已逐步转换为微服务自治:小团队开发微服务,然后通过 Restful 接口相互调用。开发者们越来越渴望能够使用一种“官话”进行流畅的沟通,甚至实现多种编程语言系统的自动化交互。

开放 API 战略( Open API Initiativev )于 2017 1 月发表声明, 2 月发布实现草案,经过反复讨论, 标准 API 规范 OAS OpenAPI-Specification 3.0 版本在 2017 6 月诞生。


OAS 3.0 架构中将 OpenAPI 赋予了以下 8 个模块的定义,其中黄色模块为必选字段,绿色模块为可选字段:

各个主要模块工作流如下所示:

以下重点说明用户获取使 OAS API 信息的三个必选部分:

1.1 API 基本信息

用户查询获取 OpenAPI 的基本定义及信息,涉及以下两个模块内容:

l    openapi

是否必选:必选

对象类型: String

类似于 XML 声明( <?xml version="1.0"?> ),用于设定文件应该使用哪一种规范进行解析。

l    info

是否必选:必选

对象类型: Info Object

这个模块主要提供 API 的元数据。

以下为一个 Info Object 样例:

title: Sample Pet Store App    # 必须,应用名称
description: This is a sample server for apetstore.   # 应用的描述
termsOfService: http://example.com/terms/      # 应用的服务条款连接
contact:      # 应用提供商的联系方式
   name: API Support
   url: http://www.example.com/support
   email: support@example.com
license:   # 应用所遵循的协议
   name: Apache 2.0
   url: http://www.apache.org/licenses/LICENSE-2.0.html
version: 1.0.1       # 应用版本

1.2 目标服务器信息

用户查询获取服务器的基本定义及信息,涉及以下模块信息:

servers

是否必选:必选

对象类型: [Server Object]

这个模块主要提供和目标服务器的连接信息,如果这个模块没有定义 url ,根据规范会自动生成一个 url / Server Object

例如:

servers:
- url: https://development.gigantic-server.com/v1  # 必选,
  description: Development server   # 非必选, url 描述

1.3 API 路径及定义

查询 API 具体参数,涉及 OAS 剩余的模块,本文主要介绍 paths components 模块。

l    paths

是否必选:必选

对象类型: Paths Object

这个模块主要提供 OpenAPI 所在的目标服务器的连接信息,如果这个模块没有定义,根据规范会自动生成一个 url / Server Object 。通过多级定义,分别确定 API paths/method ,并且通过 $ref 引用 comonents 模块中的定义,可以复用响应码等相关信息。对于携带 body 体的请求类型, requestBody 可以提供 example (或数组 examples ),这是非常灵活的(可以传入一个完整的例子,一个参考,甚至是一个 URL 的例子)。

例如:

/pets:        #URL
     get:     # 方法, get/post/..
         description: Returns all pets .    # 描述
         responses:         # 响应模块
             '200':         # 返回码为 200 ,可以使用通配符定义响应
             description: A list of pets.    # 响应描述
             content:           #Content 字段
                 application/json:
                     schema:
                         type: array 
                         items:
                             $ref: '#/components/schemas/pet' # 引用 componets

l    components

是否必选:非必选

对象类型: Components Object

这个模块主要提供每个 OpenAPI 自定义的字段定义,这部分定义的对象往往被 paths 中具体 API 进行引用:

           响应 responses

           参数 parameters

           示例 examples

           请求体 requestBodies

           标题 headers

           链接 links

           回调 callbacks

           模式 schemas

           安全体系 securitySchemes

以下为一个 Components Object 样例:

components:
     schemas: # 协议定义
         Category:
             type: object
             properties:
                 id:
                     type: integer
                     format: int64
             name:
                     type: string
         Tag:
             type: object
         properties:
                 id:
                     type: integer
                     format: int64
                 name:
                     type: string
     parameters: # 参数定义
         skipParam:
             name: skip
             in: query
             description: number of items to skip
             required: true
             schema:
                 type: integer
             format: int32
         limitParam:
             name: limit
             in: query
             description: max records to return
             required: true
             schema:
                 type: integer
             format: int32
     responses: # 返回信息定义
         NotFound:
             description: Entity not found.
         IllegalInput:
             description: Illegal input for operation.
     GeneralError:
         description: General Error
         content:
             application/json:
                 schema:
                     $ref: '#/components/schemas/GeneralError'
     securitySchemes:
         api_key:
             type: apiKey
             name: api_key
             in: header
     petstore_auth:  # 认证定义
         type: oauth2
         flows:
             implicit:
                 authorizationUrl: http://example.org/api/oauth/dialog
                 scopes:
                     write:pets: modify pets in your account
                     read:pets: read your pets

2 如何使用 OAS 设计可扩展的 OpenAPI

OpenAPI 规范包含一组有关如何设计 REST API 的强制性准则,首推协议优先的方法,而非实现优先,因此需要首先设计 API 接口,然后实现协定接口的代码。

如何实现一个优雅的 API 是一个非常具有挑战性的工作,开发者需要在庞大的后端系统的支持下,通过合适的方式将 API 暴露出去,除去单词拼写,路径设计等以外,设计优良的 OpenAPI 往往具有以下特性:

l    单一职责

单一职责是软件工程中一条著名的原则,实际在设计 API 时应确保每个 API 具有单一核心的职责,当某个 API 职责发生改变时不应该导致其他 API 发生故障和风险。 OAS 中不同的 API 可以在 paths 模块中引用多个 schema ,当我们设计新的 API 或者扩展原有 API 功能时,如果发现多个 API 多次引用相同 schema ,需重点审视每个 API 是否仍然保持单一职责。

l    抽象 API

合适的抽象 API 与业务无关的,更通用,而且方便扩展。 具体的 API 接口设计能解决特定的问题,但是在系统的扩展性和普遍适用性上则相应欠缺,因此需要针对特定的场景分析,避免 over-designed (过度设计)和 under-engineering (懒惰设计)。

举个简单的例子,我们设计一个 paths /dog API ,那么这个 API 返回的是具体 dog 的相关信息,而如果我们进行抽象设计一个 paths /pet API ,将 dog 作为参数配置在 components parameters 中,这样该 API 的扩展性进行了提升,后续扩展其他宠物比如 cat 的业务可以在不改变 API 路径的基础上进行开发,只需要更新 component parameters 即可。

l    收敛 API

提供给用户的 OpenAPI 最好支持批量数据处理,而不是让用户一次一次地调用。通过考虑多个 API 间的关联性,让用户体会到 API 的简洁性。举例来说,如果用户有可能在调用 API2 之前需要 API1 的结果,那么 API 提供者应该把 API1 API2 进行包装。这会减轻用户的记忆负担, API 收敛需要符合最少知识的原则,作为用户应该对他所使用的系统有最少的了解,而不是过多介入到系统的细节中,因此在设计 API 时候,在满足用户诉求的情况下, components 模块字段越少越好。设计者往往容易在收敛 API 时候出现无法保证单一职责的原则的情况,好的设计需要在两者之间取得一个平衡,聚焦于最终的目的 : 让使用者快好省的用起来。

l    扩展机制

在设计 API 时需要考虑未来可扩展性,为后续 API 兼容历史 API 提供支持。一方面便于开发者自身增加功能,另一方面用户也能参与进来,共建 API 生态。通过设计定义 OAS ,可以方便的按照 OAS 架构设计出面向对象、扩展性良好的 API

l    版本控制

版本控制其实是扩展的一部分,鉴于大量项目在版本控制方面都做的比较糟糕,诸如随心所欲的版本命名、前后格式不一致的版本设定、没有规范的功能迭代,因此在大版本号不变的情况下,需要保障 API 向前兼容。当 API 的大版本号改动时,意味着 API 整体有大的改动,很可能不兼容之前的 API ,同时可以提醒用户需要查询 API 更新文档进行适配,否则用户可能在更新 API 之后出现各种各样难以预测的故障。反之,如果修改小版本号则意味着这是个向前兼容的优化升级,用户可以在例行更新中采用新的 API 。这种和用户约定好的默契,可以激发用户采用新版本的热情,而不是永远不升级依赖。

l    面向扩展开发

在通过 OAS 定义完相关信息之后,优雅的 OpenAPI 在开发过程中应着重思考 API 的可配置性, API 的实现应该面向修改开放的,因此需要将相关诸如参数校验、字段长度等配置项进行抽取,在提供默认配置项的前提下可配置可修改,同时应当允许配置项的新增,例如引入 java 的可变参数类型等,这样当 OAS 文档进行修改时,可以尽可能的较少整体 API 实现的变动量。

以上列举了优雅的 OpenAPI 所具有的部分特性,与其说 OAS 设计规范是一个强制的法则,不如说是一种引导式框架,开发者通过遵循规范从而实现高效的敏捷迭代。

当完成 OpenAPI 的设计开发之后,我们需要将 API 托管到合适的平台上进行能力开放,优秀的平台减少 API 提供者的工作量,抽取公共能力使 API 提供者更加专注于业务功能开发。华为云的 API 网关集成了监控、流控、负载均衡等一系列功能,可以为开发者提供高性能、高可用的 API 托管服务,实现个人、企业 API 能力的快速开放。

关于 API 网关的详情,可以点击下面链接进行体验: https://console.huaweicloud.com/apig/?region=cn-north-1#/apig/expdemo


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/31543630/viewspace-2216837/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2018-06-25

  • 博文量
    33
  • 访问量
    21229