API设计总结
我在 2021 年作为一名应届毕业生加入了一家网络开发公司,担任前端工程师,并将在 2022 年进入我的第二年。
在实践中,我使用 React x TypeScript 开发前端,使用 Node.js (Nest) 和 Rails 开发后端 (API)。
本文的目标读者 工程师初级到中级 想要了解更多关于 API 的人 本文的目标 了解 API 了解正确的 API 设计,而不是您自己的 这篇文章没有做什么 描述如何使用特定代码编写 API 设计关于这一点,我们计划在另一篇文章中总结 OpenAPI x Swagger。
关于 API 什么是 APIAPI是“Application Programming Interface”的缩写,字面意思是“使用应用程序编程进行连接“代表着。
什么是 Web API什么是 Web API?在
Web API 是一种可以使用 HTTP 协议在网络上调用的 API。API是“Application Programming”接口的缩写,是调用软件组件和外部接口的规范,即知道功能但不知道内容行为的函数的集合(你不需要知道)从外面。指
简单来说就是一个web系统,可以通过访问URI来重写服务器端的信息,获取放置在服务器端的信息。
被解释。
通过使用 Web API,Web 服务(Twitter、Hot Pepper 等)提供的功能和数据可以以易于程序从外部读取的形式使用。
具体来说通过使用,您可以轻松获取餐厅数据。
网络如何运作一个超级简化的总结如下。
用户(客户端)向 Web 发送 HTTP 请求 请求的 Web 服务器返回数据 关于 HTTP 请求具体来说,从 Web 浏览器向 Web 服务器发送的 HTTP 请求是
请求行 标题 身体由三个要素组成。
请求行作为 HTTP 请求的内容之一的请求行如下所示。
GET /index.html HTTP/1.1在请求行“你想要什么”写,配置如下。
方法 请求 URI HTTP 版本具体方法包括GET(数据获取)、POST(数据注册)、PUT(数据更新)和DELETE(数据删除)。
请求头请求标头包含有关请求的信息和属性(元数据)。
Host: localhost:8080 Connection: keep-alive User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.98 Safari/537.36 Accept: */* Referer: http://localhost:8080/ Accept-Encoding: gzip, deflate, sdch, br Accept-Language: ja,en-US;q=0.8,en;q=0.6 Cookie: user_id=12345678请求正文实际随请求发送的数据进来了。
回复当我发送 HTTP 请求时,响应具有以下结构
状态行 标题 身体 状态行状态行具有以下结构。
HTTP 版本 状态码 短语HTTP/1.1 200 OK以下是最常见状态代码的摘要。
2xx:请求成功 4xx:错误请求 5xx:服务器端错误有关状态码的更详细说明,请参阅下面的文章。
标题响应标头包含元信息。
alt-svc: quic=":443"; ma=2592000; v="44,43,39,35" cache-control: private, max-age=0 content-encoding: br content-type: text/html; charset=UTF-8 date: Thu, 23 Aug 2018 15:37:28 GMT expires: -1 server: gws status: 200 x-frame-options: SAMEORIGIN x-xss-protection: 1; mode=block身体返回来自服务器端的特定响应数据。
关于 RESTREST 描述如下。
REST 是适用于链接分布式系统中的多个软件的设计原则之一。它是由 Roy Fielding 在 2000 年提出的。狭义上是指应用在Web系统上的软件的设计风格,在大多数情况下一般都是在这个意义上使用的。
简单地说,REST 的意思是“设计规则”。
RESTfulRESTful 意味着遵循 REST 要求的原则。
RESTful API 是指根据 REST 原则设计的 API。
REST 原则REST 有六个原则:
客户端-服务器约束 无状态 缓存(客户端) 统一接口 图层系统 按需编码 客户端-服务器约束这个想法是客户端和服务器应该是独立的和独立的,并且应该结构化,以便它们可以在不相互影响的情况下进行改进。
换句话说,将客户端(屏幕 UI)和服务器(数据)之间的关注点分开。
无国籍这意味着每个请求都独立完成而不保留先前的状态。
简而言之,
不要使用服务器上保存的上下文信息(不要使用服务器会话) 状态保存在客户端(全部包含在请求中) 缓存(客户端)客户端可以缓存响应。
适当的缓存可以减少客户端和服务器之间的通信,改善用户体验,节省资源。
统一接口对同一资源的所有 API 访问都以相同的格式统一(可通过唯一的 URI 访问)。
此外,只能使用 HTTP 协议方法(GET、POST、PUT、DELETE 等)进行数据操作。
通过统一 URI 操作(GET 和 POST),可以简化整体配置。
层系统通过组合具有多个角色的服务器来实现 API 的架构称为层系统。
具体分为接收请求的层、返回响应的层和进行安全处理的层。
分层系统可以通过使每个角色独立来增加重用。
按需编码您可以下载客户端代码并运行它。
通过加入按需代码,可以在服务器的主动下向已经发布的客户端添加功能,并且由于处理是在客户端实现的,因此可以减轻服务器的负载。
总结 REST 的原理。
客户端-服务器约束 无状态 缓存(客户端) 统一接口 图层系统 按需编码 Web API 设计从这里,我们将学习Web API的设计,这是本次的主要主题。
URI设计 简短且易于键入 不要省略 不混合大小写(基本为小写) 单词被连字符 对单词使用复数形式 不要使用需要编码的字符 易于更新 规则统一我一个一个看
简短易打字省略无用信息(重复信息)以创建简洁的 URI。
[坏的]
https://exmaple.com/service/api/search[好的]
https://exmaple.com/search不要省略[坏的]
https://exmaple.com/ja/u[好的]
https://exmaple.com/users大写和小写字母不混用(基数为小写)一般来说,使用小写字母。混合大写和小写字母很容易导致混淆。
[坏的]
https://exmaple.com/Posts[好的]
https://exmaple.com/posts连字符使用连字符连接单词。
[坏的]
https://exmaple.com/favorite_contents[好的]
https://exmaple.com/favorite-contents* 如果首先需要连接单词,则可能会审查 URI 设计。
https://exmaple.com/favorite/contents使用复数形式的单词[坏的]
https://exmaple.com/post/1[好的]
https://exmaple.com/posts/1不要使用需要编码的字符编码会降低可读性,并且无法从 URI 中猜测处理过程
[坏的]
https://exmaple.com/%TENFLOJFL$JSKF3352nb%scsd%易于更新[坏的]
https://exmaple.com/alpha/contents/1 https://exmaple.com/beta/contents/1[好的]
https://exmaple.com/contents/1统一规则统一规则,例如是否将参数作为路径参数或查询参数传递。
https://exmaple.com/beta/contents/1 # パスパラメタ https://exmaple.com/alpha/contents/?id=1 # クエリパラメタ总结 URI 设计
简短且易于键入 不要省略 不混合大小写(基本为小写) 单词被连字符 对单词使用复数形式 不要使用需要编码的字符 易于更新 统一规则 HTTP方法前面介绍的URI表示资源,HTTP方法表示对资源的操作。
具体来说,在以下情况下,向资源/api/v1/posts/1 发送请求以获取数据(GET)。
GET /api/v1/posts/1主要的HTTP方法如下。
方法名称 处理内容 得到 获取资源 邮政 新资源注册 放 更新现有资源 删除 删除资源您可以通过更改相同 URI 的方法来更改操作。
手术 蜜蜂 获取文章列表 GET方法/http:///example.com/api/v1/posts 获取单篇文章 GET方法/http:///example.com/api/v1/posts/1 创建新文章 POST 方法/http:///example.com/api/v1/posts 文章更新 PUT 方法/http:///example.com/api/v1/posts/1 删除文章 删除方法/http:///example.com/api/v1/posts/1 查询参数和路径参数 类型 蜜蜂 查询参数 http:///example.com/api/v1/posts?id=1 路径参数 http:///example.com/api/v1/posts/1何时使用查询参数和路径参数
表示唯一资源路径参数利用 如果可以省略查询参数具体而言,使用查询参数是因为无法确定搜索请求的唯一路径。
http:///example.com/api/v1/users?name="suzuki"状态码状态码给出了处理结果的概览。
即使发生特定错误,您也可以通过跟踪状态代码来识别错误。
有关状态代码,请参阅本文。
响应数据格式主要响应数据的格式如下。
XML JSON XMLXML的特点如下。
文本格式在 标签中描述 标签是嵌套的 标签有属性[XML 格式]
<login> <username>useremail@company.com</username> <password>mypassword</password> </login>JSONJSON的特点如下。
文本格式 基于 JavaScript 的格式 与 XML 相比,可以减少数据量 对象可以嵌套[JSON格式]
{ user: {"id" : "1", "name" : "tanaka"} }在指定数据格式时,最好在请求头中进行描述。
[请求头]
GET http://example.com/users Host: exmaple.com Acceot: application/json # JSON形式と指定した場合数据内部结构设计 不要使用信封 减少嵌套 统一属性命名约定 指定日期 不要使用信封不要使用信封,它是返回 JSON 的 API 的常见部分。
下面响应中包含的“header”部分与请求头中传递的描述相同,因此不需要。 (涵盖的信息)
[有信封时 (BAD)]
{ "header": { "code": "0", "message": "success" }, "result": { "books": [ { "id": 1, "name": "初めてのJavaScript", "price": 3000 }, { "id": 2, "name": "はじめてのAPI入門", "price": 1500 } ] } }[省略信封时(GOOD)]
{ "books": [ { "id": 1, "name": "はじめてのJavaScript", "price": 3000 }, { "id": 2, "name": "はじめてのAPI入門", "price": 1500 } ] }减少嵌套嵌套增加了响应能力,因此设计响应以减少不必要的嵌套。
[如果有不必要的嵌套 (BAD)]
{ "id": 2, "name": "はじめてのAPI入門", "info" : { "author": "tanaka", "price": 1500 } }[省略不必要的嵌套时(好)]
{ "id": 2, "name": "はじめてのAPI入門", "author": "tanaka", "price": 1500 }统一属性命名约定一般使用蛇皮套或骆驼皮套。
姓名 例子 蛇案 蛇案例 骆驼香烟盒 骆驼香烟盒 帕斯卡案例 帕斯卡案例 日期指定对日期使用 RFC3339 (W3C-DTF) 格式
2022-10-31T18:00:00+09:00错误将错误详细信息添加到响应正文。
{ "code": "12345", "message": "認証エラーです" }此外,发生错误时,请勿以 HTML 格式响应。
根据格式,可能无法在客户端处理它。
其他设计 认证 JSON 网络令牌JSON Web Token (JWT) 被称为“jot”,通过签名对 JSON 格式的数据进行篡改检查。
通过使用 JWT,可以将认证结果存储在客户端,而无需存储在服务器端,实现无状态通信。
JWT的结构如下。
标题 有效载荷 签名[智威汤逊示例]
eyJhbGcGKOWJIUzI1NiI&3Hf5cCI6IkpXVCJ9. eyJzdWIiOiIxMjMPqfwibmFtZSIfksjDTW3nwoAOCWQ0IjoxNTE2MjM5MDIyfQ. t42p4AHef69Tyyi880842bDTTOADINW93ncs7Zffs.,实际上具有以下结构
[ヘッダ]. [ペイロード]. [署名]标头具体定义了签名中使用的算法。
【标题】
{ "alg": "HS256", "typ": "JWT" }有效负载包含您要存储的实际数据。
sub 是同一颁发者中的标识符(用户 ID 等) iat 表示发出 jwt 的日期和时间【有效载荷】
{ "sub": "1234567890", "iat": 1516239022 }签名验证数据未被篡改。
授权标头有一个 Authorization 标头作为用于身份验证的标头。
使用前面介绍的 JWT 时,将令牌存储在 Authorization 标头中并发送请求。
它以以下格式描述。
Authorization: [type] [credentials][type] 的类型如下。
姓名 解释 基本的 使用基本身份验证以纯文本形式发送 ID 和密码 承载 JWT 在 OAuth2.0 中使用它 消化 散列和发送带有摘要认证的 ID 和密码 身份验证 OAuth 1.0此外,[credentials] 将包含特定的身份验证信息。
使用著名的身份验证方法 Auth0,您可以使用 JWT 令牌在请求标头中包含以下信息,从而与服务器端交换数据。
Authorization: Bearer eyxxxxxxxxx安全我们将解释以下漏洞对策。
XSS CSRF HTTP 智威汤逊 跨站脚本XSS 允许恶意用户在合法站点上嵌入恶意脚本,并非法提取有关合法用户的信息。
作为对策,将以下内容添加到响应标头中
X-XSS-Protection: 1 启用 XSS 过滤 X-Frame-Options: 用 DENY 拒绝调用帧标签 X-Content-Type-Options: 使用 nosniff 解决 IE 漏洞 CSRF处理来自应拒绝的访问源的请求。
以下是对策
未经许可拒绝请求 X-API-密钥 身份验证 恶意攻击者发出难以猜测的令牌并执行验证X-CSRF-TOKEN HTTP由于 HTTP 通信路径没有加密,因此很容易被窃听。
作为对策,请使用 HTTPS。
智威汤逊前面介绍的JWT可以在客户端进行编辑,所以如果服务端验证不充分,就有可能接受被篡改的信息。
作为对策,不要为标头算法 (alg) 指定 none。
在最后怎么样。这里是 API 设计的总结。
我正在写其他各种文章,所以如果您能阅读它,我会很高兴。
参考
原创声明:本文系作者授权爱码网发表,未经许可,不得转载;
原文地址:https://www.likecs.com/show-308632569.html