当前位置:首页 > 数码 > API-如何设计-终极指南 (api如何获取)

API-如何设计-终极指南 (api如何获取)

admin5个月前 (05-09)数码30

在前后端分离的设计中,后端需要提供 WebAPI 给前端使用。如果是一个平台级的产品,还有可能需要将平台的公共 API 提供给第三方系统使用,这些都要考虑到 API 的设计。

常见问题

问题 1:客户端种类比较多,不容易实现差异化 不同的客户端在调用接口时,输入输出会存在差异,比如:移动端的数据列表功能和结构上比 PC 端要简单很多,如果调用统一的接口,会造成浪费。 问题 2:客户端直接对 API 进行调用 客户端直接调用后端 API,存在安全隐患,也无法统一控制 API 的访问和使用。

解决方式

API 网关 API 网关是一种服务,是外部进入到应用程序内部的入口点。负责请求路由、身份验证、限流、熔断、流量监控等各种功能。 请求路由 API 网关的核心功能是请求路由。当网关收到请求时,会去查询路由映射关系,将请求指定到相应的服务。这跟反向代理有点类似。 路由的配置可以是静态的,也可以是动态的。比如在 Ocelot 中,可以在 json 文件中进行路由映射的配置,也可以使用代码的方式按照需求进行动态路由修改。 组合多个服务 在使用平台搭建的业务系统中,打开数据列表的详情,会做下面几件事情: 1. 获取数据列表 2. 获取数据详情 在 API 网关中可以对客户端提供统一入口调用,将这些来自不同服务的接口进行整合,统一输出。因为网关和服务都在内网,传输速度比较快,和客户端需要同时获取多个 API 请求相比,提升了效率。 专属 API 作为一个平台,对外提供的公共 API 颗粒度往往不会很细,否则就不具备通用性了。如果针对不同的移动端(安卓、iOS)、或者特定的第三方平台,有一些细节上的区别。网关可以为不同类型的客户端提供独立的 API。 一些扩展能力 这些扩展能力并非只有在 API 网关中才能实现,在后端服务中一样可以。但有些能力放到 API 网关中会更合适。例如:身份认证、限流、熔断等,就是在请求还为触及服务时就已经处理了,会更加安全,也会让后端服务更稳固。

网关的选择

在 .NET Core 中可以选择的开源网关产品有:Ocelot、Kong、Envoy 等。 Ocelot Ocelot 是一个基于 .NET Core 的轻量级 API 网关,用于构建和管理微服务架构中的 API 网关。作为一个开源项目,Ocelot 提供了一种灵活、可扩展的方式来集中处理请求路由、认证授权、请求转发、负载均衡和缓存等功能。 Kong Kong 是在 Nginx 中运行的 Lua 程序。得益于 Nginx 的性能优势,Kong 相比于其它的开源 API 网关来说,性能方面是最好的。由于大中型公司对于 Nginx 运维能力都比较强,所以选择 Kong 作为 API 网关,无论是在性能还是在运维的把控力上,都是比较好的选择。 Envoy Envoy 是一款开源的高性能代理和通信中间件,专为云原生应用程序设计。它由 Lyft 开发并于 2017 年成为 CloudNative Computing Foundation(CNCF)的毕业项目之一。虽然 Envoy 本身是用 C++ 编写的,但它可以与任何语言和框架进行集成,包括 .NET Core。 网关的选择需要能解决当前面临的问题。关于各种网关的使用方式,以及优缺点的对比,后面再进行详细介绍。

最后

不管是 API 的设计还是代码架构的设计,原则其实都差不多,要能够松耦合、易扩展、在满足现有需求的基础上,再多往前想一步,避免过度设计。

API 设计规范

设计时通过将请求和响应之间的不同部分隔离来让事情变得简单。保持简单的规则让我们能更关注在一些更大的更困难的问题上。

请求和响应将解决一个特定的资源或集合。使用路径(path)来表明身份,body来传输内容(content)还有头信息(header)来传递元数据(metadata)。查询参数同样可以用来传递头信息的内容,但头信息是首选,因为他们更灵活、更能传达不同的信息。

所有的访问API行为,都需要用TLS通过安全连接来访问。没有必要搞清或解释什么情况需要TLS 什么情况不需要TLS,直接强制任何访问都要通过 TLS。

理想状态下,通过拒绝所有非TLS请求,不响应http或80端口的请求以避免任何不安全的数据交换。如果现实情况中无法这样做,可以返回403 Forbidden响应。

把非TLS的请求重定向(Redirect)至TLS连接是不明智的,这种含混/不好的客户端行为不会带来明显好处。依赖于重定向的客户端访问不仅会导致双倍的服务器负载,还会使 TLS 加密失去意义,因为在首次非TLS调用时,敏感信息就已经暴露出去了。

制定版本并在版本之间平缓过渡对于设计和维护一套API是个巨大的挑战。所以,最好在设计之初就使用一些方法来预防可能会遇到的问题。

为了避免API的变动导致用户使用中产生意外结果或调用失败,最好强制要求所有访问都需要指定版本号。请避免提供默认版本号,一旦提供,日后想要修改它会相当困难。

最适合放置版本号的位置是头信息(HTTP Headers),在 Accept 段中使用自定义类型(contenttype)与其他元数据(metadata)一起提交。例如:

在所有返回的响应中包含ETag头信息,用来标识资源的版本。这让用户对资源进行缓存处理成为可能,在后续的访问请求中把If-None-Match头信息设置为之前得到的ETag值,就可以侦测到已缓存的资源是否需要更新。

为每一个请求响应包含一个Request-Id头,并使用UUID作为该值。通过在客户端、服务器或任何支持服务上记录该值,它能为我们提供一种机制来跟踪、诊断和调试请求。

一个大的响应应该通过多个请求使用Range头信息来拆分,并指定如何取得。详细的请求和响应的头信息(header),状态码(status code),范围(limit),排序(ordering)和迭代(iteration)等,参考 Heroku PlatformAPI discussion of Ranges .

在 PUT/PATCH/POST 请求的正文(request bodies)中使用JSON格式数据,而不是使用form 表单形式的数据。这与我们使用JSON格式返回请求相对应,例如:

资源名 (Resource names):使用复数形式为资源命名,除非这个资源在系统中是单例的 (例如,在大多数系统中,给定的用户帐户只有一个)。 这种方式保持了特定资源的统一性。

行为 (Actions):好的末尾不需要为资源指定特殊的行为,但在特殊情况下,为某些资源指定行为却是必要的。为了描述清楚,在行为前加上一个标准的actions:

例如:

为了和域名命名规则保持一致,使用小写字母并用 - 分割路径名字,例如:

属性也使用小写字母,但是属性名要用下划线 _ 分割,以便在Javascript****中省略引号。例如:

在某些情况下,让用户提供ID去定位资源是不方便的。例如,一个用户想取得他在Heroku平台app信息,但是这个app的唯一标识是UUID。这种情况下,你应该支持接口通过名字和ID都能访问,例如:

不要只接受使用名字而放弃了使用id。

在一些有父路径/子路径嵌套关系的资源数据模块中,路径可能有非常深的嵌套关系,例如:

推荐在根(root)路径下指定资源来限制路径的嵌套深度。使用嵌套指定范围的资源。在上述例子中,dyno属于app,app属于org可以表示为:

为每一次的响应返回合适的HTTP状态码。好的响应应该使用如下的状态码:

200: GET请求成功,及DELETE或PATCH同步请求完成,或者PUT同步更新一个已存在的资源;

201: POST同步请求完成,或者PUT同步创建一个新的资源;

202: POST,PUT,DELETE,或PATCH请求接收,将被异步处理;

206: GET 请求成功,但是只返回一部分;

使用身份认证(authentication)和授权(authorization)错误码时需要注意:

401 Unauthorized: 用户未认证,请求失败;

403 Forbidden: 用户无权限访问该资源,请求失败;

当用户请求错误时,提供合适的状态码可以提供额外的信息:

422 Unprocessable Entity: 请求被服务器正确解析,但是包含无效字段;

429 Too Many Requests: 因为访问频繁,你已经被限制访问,稍后重试;

500 Internal Server Error: 服务器错误,确认状态并报告问题.

对于用户错误和服务器错误情况状态码,参考: ** **HTTP response code spec

提供全部可显现的资源表述 (例如:这个对象的所有属性) ,当响应码为200或是201时返回所有可用资源,包含 PUT/PATCH和 DELETE 请求,例如:

当请求状态码为202时,不返回所有可用资源,例如:

在默认情况给每一个资源一个id属性。除非有更好的理由,否则请使用UUID。不要使用那种在服务器上或是资源中不是全局唯一的标识,尤其是自动增长的id。

生成小写的UUID格式 8-4-4-4-12,例如:

为资源提供默认的创建时间 created_at 和更新时间 updated_at,例如:

有些资源不需要使用时间戳那么就忽略这两个字段。

仅接受和返回UTC格式的时间。ISO8601格式的数据,例如:

使用嵌套对象序列化外键关联,例如:

而不是像这样:

这种方式尽可能的把相关联的资源信息内联在一起,而不用改变资源的结构,或者引入更多的顶层字段,例如:

响应错误的时,生成统一的、结构化的错误信息。包含一个机器可读的错误 id,一个人类可读的错误信息(message),根据情况可以添加一个url来告诉客户端关于这个错误的更多信息以及如何去解决它,例如:

文档化错误信息格式,以及客户端可能遇到的错误信息id。

客户端的访问速度限制可以维护服务器的良好状态,保证为其他客户端请求提供高性的服务。你可以使用 token bucket algorithm 技术量化请求限制。

为每一个带有RateLimit-Remaining响应头的请求,返回预留的请求tokens。

如何设计

请求中多余的空格会增加响应大小,而且现在很多的HTTP客户端都会自己输出可读格式(prettify)的JSON。所以最好保证响应JSON最小化,例如:

而不是这样:

你可以提供可选的方式为客户端提供更详细可读的响应,使用查询参数(例如:?pretty=true)或者通过Accept头信息参数(例如:Accept:application/+json;version=3; indent=4;)。

提供一个机器可读的模式来恰当的表现你的API。使用 prmd 管理你的模式,并且确保用prmd verify验证是有效的。

提供人类可读的文档让客户端开发人员可以理解你的API。

如果你用prmd创建了一个概要并且按上述要求描述,你可以为所有节点很容易的使用prmd doc生成Markdown文档。

除了节点信息,提供一个API概述信息:

提供可执行的示例让用户可以直接在终端里面看到API的调用情况,最大程度的让这些示例可以简单的使用,以减少用户尝试使用API的工作量。例如:

如果你使用 prmd 生成Markdown文档,每个节点都会自动获取一些示例。

描述您的API的稳定性或是它在各种各样节点环境中的完备性和稳定性,例如:加上原型版(prototype)/开发版(development)/产品版(production)等标记。

更多关于可能的稳定性和改变管理的方式,查看 ** **Heroku API compatibility policy

一旦你的API宣布产品正式版本及稳定版本时,不要在当前API版本中做一些不兼容的改变。如果你需要,请创建一个新的版本的API。

如何实现微信公众平台消息接口》API指南

微信公众平台分为订阅号和服务号,服务号提供9大接口,需要通过微信认证后才能使用这些接口。认证费用300元。下面是接口的大致介绍:

语音识别:通过语音识别接口,用户发送的语音,将会同时给出语音识别出的文本内容。

客服接口:通过客服接口,公众号可以在用户发送过消息的24小时内,向用户回复消息。

OAuth2.0网页授权:通过网页授权接口,公众号可以请求用户授权。

生成带参数二维码:通过该接口,公众号可以获得一系列携带不同参数的二维码,在用户扫描关注公众号后,公众号可以根据参数分析各二维码的效果。

获取用户地理位置:通过该接口,公众号能够获得用户进入公众号会话时的地理位置(需要用户同意)。

获取用户基本信息:通过该接口,公众号可以根据加密后的用户OpenID,获取用户的基础信息,包括头像、昵称、性别、地区。

获取关注者列表:通过该接口,公众号可以获取所有关注者的OpenID。

用户分组接口:通过分组接口,公众号可以在后台为用户移动分组,或创建、修改分组。

上传下载多媒体文件:通过该接口,公众号可以在需要时在微信服务器上传下载多媒体文件。

免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。

标签: API

“API-如何设计-终极指南 (api如何获取)” 的相关文章

优雅成功API接口开关-让你的运行掌控全局 (优雅成功的现代女性)

优雅成功API接口开关-让你的运行掌控全局 (优雅成功的现代女性)

环境:SpringBoot2.7.12 1.概述 本文将引见如何为API接口灵活减少开关性能。经过这特性能,咱们可以控制API接口的反常访问或显示揭示消息。这有助于在开发和保养环节中更...

每个API战略的不可动摇戒律

每个API战略的不可动摇戒律

随着本世纪初 Amazon、eBay 和 Salesforce 等公司的兴起,网络应用程序接口 (API) 标准化趋势应运而生。开放式网络 API 的网络不断扩大,让所有人可以使用这些 API,这...

REST-的十个最佳实践-API-构建强大 (rest的过去形态)

REST-的十个最佳实践-API-构建强大 (rest的过去形态)

在项目开发中,REST 风格的 API 设计非常普遍。以下 10 条最佳实践旨在为你的 REST API 提供灵感和指导。 1. 使用具体且有意义的资源名称 选择准确表示所代表实体的资...

API恳求重试的8种方法-哪种最适宜你的运行

API恳求重试的8种方法-哪种最适宜你的运行

重试机制成功8种方式 1.循环重试 这是最繁难也最间接的一种方式。在恳求接口的代码块中参与循环,假设恳求失败则继续恳求,直到恳求成功或到达最大重试次数。 示例代码: intre...

在零信任世界中实现API安全性的全面指南 (零信任 sase)

在零信任世界中实现API安全性的全面指南 (零信任 sase)

API 安全性与零信任:融合原则和实践 引言 随着现代网络格局的不断演变,零信任架构 (ZTA) 已从一种抽象概念转变为许多企业组织积极实施的安全战略。在许多 ZTA 实施计划中,常常忽视对 A...