简述使用REST API 的最佳实践

Facebook,Google,Github,Netflix,Amazon和Twitter等许多巨头都拥有自己的REST(ful)API,您可以访问它们来获取甚至写入数据。

但是,为什么所有都需要REST?

那样好吗,为什么如此盛行?

当然,这不是传达消息的唯一方法吗?

REST和HTTP有什么区别?

好吧,事实证明REST非常灵活,并且与 Internet所基于的主要协议HTTP兼容。由于它是一种架构风格而不是标准,因此它提供了实现各种设计最佳实践的大量自由。以及听说它与语言无关?你一定觉得它很棒吧。

在此博客文章中,我们的目标是尽可能清楚地解释REST,以便您可以清楚地了解何时以及如何使用REST,以及它的本质。

我们将介绍一些基础知识和定义,并展示一些REST API最佳实践。这应该为您提供了以您喜欢的任何编码语言实现REST API所需的全部知识。

如果您对HTTP不太熟悉,建议您阅读我们的HTTP系列文章[1],或者至少阅读其中的第1部分[2],这样您可以更轻松地理解这些资料。

因此,在这篇文章中,我们将讨论:

关于REST:

•什么是REST?[3]•REST是否绑定到HTTP?[4]•REST和HATEOAS支持[5]•RESTful API是什么意思?[6]•REST过多又称为RESTafarian综合征[7]

REST API最佳做法:

•抽象与具体API[8]•URI格式(名词,不是动词)。正确网址与错误网址示例[9]•错误处理[10]•状态码[11]•安全[12]•REST API版本控制[13]•文件的重要性[14]

那么REST本质上是什么?

REST(代表性状态转移)是Roy Fielding[15]在其博士学位中创立的一种建筑风格。UC Irvine的论文“ 体系结构样式和基于网络的软件体系结构设计[16] ”。他与HTTP 1.1同步提出了这种观点。

我们主要将REST用作在万维网上的计算机系统之间进行通信的一种方式。

REST是否绑定到HTTP?

根据定义,似乎与Http强制绑定?其实并非如此。尽管您可以将其他一些应用程序协议与REST一起使用,但是在实现REST时,HTTP[17]仍然是应用程序协议中无可争议的冠军。

REST和HATEOAS支持

作为应用程序状态引擎的 HATEOAS或超媒体 是每个可扩展且灵活的REST API的重要功能。

该HATEOAS[18]约束建议,客户端和服务器通信完全采用了超媒体[19]

使用超媒体有几个优点:

•使API设计人员能够在每个响应中包括他们所能提供的一切,以正确地提供一件事以及与相关端点的超媒体链接,从而使设计脱钩•帮助API更优雅地发展和成熟•为用户提供更深入地探索API的方法

因此很明显,HATEOAS在设计时考虑了耐用性

GitHub的工作方式如下:

GET https://api.github.com/users/codemazeblog

响应:

{"login": "CodeMazeBlog","id": 29179238,"avatar_url": "https://avatars0.githubusercontent.com/u/29179238?v=4","gravatar_id": "","url": "https://api.github.com/users/CodeMazeBlog","html_url": "https://github.com/CodeMazeBlog","followers_url": "https://api.github.com/users/CodeMazeBlog/followers","following_url": "https://api.github.com/users/CodeMazeBlog/following{/other_user}","gists_url": "https://api.github.com/users/CodeMazeBlog/gists{/gist_id}","starred_url": "https://api.github.com/users/CodeMazeBlog/starred{/owner}{/repo}","subscriptions_url": "https://api.github.com/users/CodeMazeBlog/subscriptions","organizations_url": "https://api.github.com/users/CodeMazeBlog/orgs","repos_url": "https://api.github.com/users/CodeMazeBlog/repos","events_url": "https://api.github.com/users/CodeMazeBlog/events{/privacy}","received_events_url": "https://api.github.com/users/CodeMazeBlog/received_events","type": "User","site_admin": false,"name": "Code Maze","company": "Code Maze","blog": "https://code-maze.com","bio": "A practical programmers' resource.",...
}

如您所见,除了客户端请求的关键信息之外,您还可以在响应中找到一堆相关的超媒体链接,这些链接将您带到您可以自由浏览的API的其他部分。

RESTful API是什么意思?

“ RESTful”意味着一些功能:

客户端-服务器体系结构[20]完整的服务由作为整个系统前端的“客户端”和作为后端的“服务器”组成•无状态:服务器不应在不同请求之间保存任何状态。会话状态完全由客户负责。按照REST定义: 所有REST交互都是无状态的。也就是说,每个请求都包含连接器理解该请求所需的所有信息,而与之前的任何请求无关。(Roy的论文ch.5.2.2[21])\可缓存的[22]客户端应该能够将响应存储在缓存中以提高性能

因此,RESTful API是一项遵循这些规则的服务(希望如此),并使用HTTP方法[23]来操纵资源集。

但是为什么我们需要或使用RESTful API?

因为它们为我们提供了一种简单,灵活和可扩展的方式来制作可通过Internet进行通信的分布式应用程序。

我们可以拥有更多的REST方法吗?

是的,你猜对了。是的,我们可以????

正如Mike Schinkel[24]定义的那样,对于狂热地遵循REST的人们来说甚至还有一个短语 。[25]

RESTifarian是Roy T. Fielding在他的博士论文第五章中定义的REST软件架构风格的狂热支持者。论文在UCIrvine。你可以在rest - discussion邮件列表中找到野外的RESTifarians。但是要小心,RESTifarians在讨论休息的细节时可能是极其细致的,正如我最近在参与列表时所了解到的。????

太多的事情都是不好的。

我们需要一点实用主义才能做出好的应用程序和服务。了解和理解一种理论很重要,但是该理论的实现是区分不良与良好与卓越应用的区别。所以要聪明,要牢记最终用户。

因此,让我们走一些使API变得“光彩”的重要点,使用户的生活变得更加轻松。

抽象与具体API

在开发软件时,我们经常使用抽象和多态来获取大多数应用程序。我们想重用尽可能多的代码。

那么我们也应该这样写我们的API吗?

好吧,API并非完全如此。对于REST API,具体要比abstract好。你能猜出为什么吗?

让我向您展示一些示例:

让我们看两个API版本。它是最好有有一个的API /entities,或者有一个API /owners/blogs并 /blogposts 分别?

作为开发人员,哪一个对您更具描述性?您想使用哪个API?

我总是会选择第二个。

URI格式(名词,不是动词)。正确网址与错误网址示例

这是另一种REST API最佳实践。您应该如何格式化端点?

如果使用软件开发方法,您将得到如下所示的结果:

/getAllBlogPosts
/updateBlogPost/12
/deleteBlogPost/12
/getAuthorById/3
/deleteAuthor/3
/updateAuthor/3

您明白了……会有很多端点,每个端点都在做其他事情。有一个更好的系统可以解决这些问题。

将资源视为名词,将HTTP方法视为动词。如果这样做,最终将得到如下结果:

GET /blogposts –获取所有博客文章

GET /blogposts/12 –获取ID为12的博客文章

POST /blogposts –添加新的博客文章并返回详细信息

DELETE /blogposts/12 –删除ID为12的博客文章

GET /authors/3/blogposts –获取ID为3的作者的所有博客文章

这是创建API的更简洁,更精确的方法。对于最终用户而言,这是显而易见的,并且有一种解决方法。

通过使用单数而不是复数来表示资源名称,可以使其更加简洁。那取决于你。

错误处理

API构建的另一个重要方面。有几种处理错误的好方法。

让我们看看顶级狗如何做到这一点:

推特:

•请求: GET https://api.twitter.com/1.1/account/settings.json•响应:状态码400Twitter response

  {"errors":[{"code":215,"message":"Bad Authentication data."}]}

Twitter为您提供状态代码和错误代码,并简要描述了所发生错误的性质。他们让您在“ 响应代码”[26]页面上查找代码。

脸书:

•请求: GET https://graph.facebook.com/me/photos•响应:状态码400Facebook Response

{ "error": { "message": "An active access token must be used to query information about the current user.", "type": "OAuthException", "code": 2500, "fbtrace_id": "DzkTMkgIA7V" }}

Facebook为您提供了更具描述性的错误消息。

特威里奥:

•请求: GET https://api.twilio.com/2010-04-01/Accounts/1234/IncomingPhoneNumbers/1234•响应:状态码404

<?xml version='1.0' encoding='UTF-8'?><TwilioResponse> <RestException> <Code>20404</Code> <Message>The requested resource /2010-04-01/Accounts/1234/IncomingPhoneNumbers/1234 was not found</Message> <MoreInfo>https://www.twilio.com/docs/errors/20404</MoreInfo> <Status>404</Status> </RestException></TwilioResponse>

Twilio默认为您提供XML响应,并提供指向文档的链接,您可以在其中找到错误的详细信息。

如您所见,错误处理的方法因实现而异。

重要的是 不要让REST API的用户“挂断”,不知道发生了什么,或者漫无目的地在StackOverflow的浪费中徘徊,寻找解释。

状态码

在设计REST API时,我们通过使用HTTP状态代码[27]与API用户进行通信 。状态代码很多,描述了多种可能的响应。

但是,我们应该使用多少? 我们在每种情况下都应该有严格的状态码吗?

就像生活中的许多事情一样, KISS原则[28] 也适用于这里。那里有70多个状态代码。你内心了解他们吗?潜在的API用户会全部了解它们,还是会再次使用Google搜索?

大多数开发人员都熟悉最常见的状态代码:

**200 OK****400 Bad Request****500 Internal Server Error**

从这三个开始,您可以涵盖REST API的大多数功能。

其他常见的代码包括:

**201 Created****204 No Content****401 Unauthorized****403 Forbidden****404 Not Found**

我们可以使用它们来帮助用户快速找出结果。如果您感觉到状态代码的描述性不如我们在“错误处理”部分中讨论的那样,则可能应该包含某种消息。再一次,我们需要务实,通过使用 数量有限的代码 和描述性消息来帮助用户。

您可以在此处[29]找到完整的HTTP状态代码列表,以及在CodeMaze上总结的[30]其他有用的HTTP内容 。

安全

关于REST API安全的[31]说法不多,因为 REST不处理安全问题。它依赖于诸如基本身份验证或摘要身份验证之[32]类的标准HTTP机制 。

每个请求都应 通过HTTPS进行

有很多技巧可以提高REST API的安全性,但是由于REST的无状态性,因此在实施它们时必须谨慎。记住最后一个请求的状态超出了窗口,应该在 客户端存储和验证状态。

时间戳记和日志记录 请求也可以有所帮助。

关于这个话题还有很多要说的,但这超出了本文的范围。我们有一个不错的职位HTTP安全[33] 在这里CodeMaze如果您想了解更多关于这一点。

REST API版本控制

您已经编写了REST API,它已经非常成功,许多人已经使用它并对此感到满意。但是,您拥有的多汁的新功能会破坏系统的其他部分。重大变化。

不用担心,有解决方案!

在开始制作您的API之前,我们可以通过在端点之前加上API版本来对其进行版本控制: https://api.example.com/v1/authors/2/blogposts/13

这样,只要API发生重大更改,我们就可以始终增加API版本号(例如v2,v3…)。这也向用户发出信号,表明已发生了翻天覆地的变化,在使用新版本时,请务必小心。

文件的重要性

这是不言而喻的。您可能是世界上最好的API设计人员,但是 如果没有文档,您的API就像死了一样。

正确的文档 对于每个软件产品和Web服务都是必不可少的。

我们可以通过保持一致并使用清晰和描述性的语法来帮助用户。但是,好的文档页面并没有真正的替代品。

一些很好的例子:

https://www.twilio.com/docs/api/rest/

https://developers.facebook.com/docs/

https://developers.google.com/maps/documentation/

还有很多其他...

有许多工具可以帮助您记录您的API,但是不要忘记让人参与其中,只有一个人可以正确地理解另一个人。至少现在是这样(看着你)。

结论

我们讨论了REST API构建的许多概念,并介绍了一些顶级REST API最佳实践。在一次提供这些API时,您可能会觉得有些奇怪或难以接受,但是请尝试自己创建REST API。并尝试实现一些您在这里学到的REST API最佳实践。

References

[1] HTTP系列文章: https://code-maze.com/http-series/
[2] 第1部分: https://code-maze.com/http-series-part-1/
[3] 什么是REST?: https://code-maze.com/top-rest-api-best-practices/#whatisrest
[4] REST是否绑定到HTTP?: https://code-maze.com/top-rest-api-best-practices/#restbound
[5] REST和HATEOAS支持: https://code-maze.com/top-rest-api-best-practices/#hateoas
[6] RESTful API是什么意思?: https://code-maze.com/top-rest-api-best-practices/#whatdoesitmean
[7] REST过多又称为RESTafarian综合征: https://code-maze.com/top-rest-api-best-practices/#restafarian
[8] 抽象与具体API: https://code-maze.com/top-rest-api-best-practices/#abstractvsconcrete
[9] URI格式(名词,不是动词)。正确网址与错误网址示例: https://code-maze.com/top-rest-api-best-practices/#urlformat
[10] 错误处理: https://code-maze.com/top-rest-api-best-practices/#errorhandling
[11] 状态码: https://code-maze.com/top-rest-api-best-practices/#statuscodes
[12] 安全: https://code-maze.com/top-rest-api-best-practices/#security
[13] REST API版本控制: https://code-maze.com/top-rest-api-best-practices/#versioning
[14] 文件的重要性: https://code-maze.com/top-rest-api-best-practices/#documentation
[15] Roy Fielding: https://en.wikipedia.org/wiki/Roy_Fielding
[16] 体系结构样式和基于网络的软件体系结构设计: https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm
[17] HTTP: https://code-maze.com/http-series/
[18] HATEOAS: https://en.wikipedia.org/wiki/HATEOAS
[19] 超媒体: https://en.wikipedia.org/wiki/Hypermedia
[20] 客户端-服务器体系结构: https://code-maze.com/http-series-part-2
[21] Roy的论文ch.5.2.2: https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm
[22] 可缓存的: https://code-maze.com/http-series-part-2/#caching
[23] HTTP方法: https://code-maze.com/the-http-reference/#requestmethods
[24] Mike Schinkel: http://mikeschinkel.com/about/
[25] 。: http://mikeschinkel.com/about/
[26] 响应代码”: https://developer.twitter.com/en/docs/basics/response-codes
[27] HTTP状态代码: https://code-maze.com/the-http-reference/#statuscodes
[28] KISS原则: https://en.wikipedia.org/wiki/KISS_principle
[29] 此处: https://code-maze.com/the-http-reference
[30] 在CodeMaze上总结的: https://code-maze.com/the-http-reference
[31] REST API安全的: https://blog.restcase.com/top-5-rest-api-security-guidelines/
[32] 基本身份验证或摘要身份验证之: https://code-maze.com/http-series-part-4/
[33] HTTP安全: https://code-maze.com/http-series-part-5/

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

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

相关文章

sap 标准委外和工序委外_SAP FICO零基础学习_0035_标准成本估算-主数据-物料主数据...

前辈的第35堂课&#xff1a;谢谢大家的喜欢和关注噢~这里的“前辈”其实指的是给我讲课的前辈啦&#xff0c;我不是前辈噢&#xff0c;我只是一个刚刚接触FICO的小白&#xff0c;跟大家分享前辈给我讲的东西。因为刚接触&#xff0c;学习的内容比较简单~有基础的小伙伴可以去看…

[Java基础]线程安全的类

package ThreadDemoPack01;import java.util.*;public class ThreadDemo01 {public static void main(String[] args){StringBuffer sb new StringBuffer();//线程安全StringBuilder sb2 new StringBuilder();//线程不安全Vector<String> v new Vector<String>(…

数据结构与算法-- 八皇后问题(多种实现方案)

八皇后问题解法一(排列筛选法) 本篇我们承接上一篇中的思想&#xff0c;想到了一个经典的算法题&#xff0c;八皇后问题&#xff1a;题目&#xff1a;在8*8的国际象棋上摆放8个皇后&#xff0c;使得其互相不能攻击&#xff0c;即任意两个换后不能在同一行&#xff0c;同一列&a…

Blazor WebAssembly 3.2.0 正式起飞,blazor 适合你吗?

最近blazor更新很快&#xff0c;今天在官方博客上发布了Blazor WebAssembly 3.2.0 RC&#xff1a;https://devblogs.microsoft.com/aspnet/blazor-webassembly-3-2-0-release-candidate-now-available/ &#xff0c;这是最后一次预览版了&#xff0c;功能开发都已经完成。5.19的…

中获取文件名不要扩展名_如何批量修改文件名,3s时间够不够

?点击关注Excel表哥公众号上一篇推文我们介绍了如何批量获取同一文件夹下所有的文件名。▲点此图片回顾很多读者获取到这些文件名之后的一种工作情形就是需要批量或者有针对性地修改这些文件的名称。那么但凡是这类需要批量操作的重复工作&#xff0c;Excel擅长。还是以上篇推…

数据结构与算法--死磕二叉树

死磕二叉树 近一年都比较关注算法相关的知识&#xff0c;也刷了不少题&#xff0c;之前的文章中大多也是算法相关的文章&#xff0c;但是感觉每次遇到树相关的题型都不能应对自如&#xff0c;因此还是有必要在相关知识上下功夫&#xff0c;因此有此次总结&#xff0c;以下是所…

Jenkins 中以构建 Tag 来实现版本管理

好的工具和流程能使我们事半功倍&#xff0c;而这个过程是不断迭代和演进的。关于这一块的内容&#xff0c;之前写过几篇文章&#xff1a;在团队中使用GitLab中的Merge Request工作模式敏捷下的需求和代码分支管理不断进化的分支和需求管理现在又有了些新的变化和改进&#xff…

将字符串添加负数_Go语言实现LeetCode算法:8 字符串转整数

Go语言中文网&#xff0c;致力于每日分享编码、开源等知识&#xff0c;欢迎关注我&#xff0c;会有意想不到的收获&#xff01;看到题目&#xff0c;是不是超级简单&#xff0c;用 strconv.Atoi 就可以了&#xff1f;题目当然不是这么简单的要求。1 题目描述实现atoi函数&#…

[Java基础]生产者和消费者模式概述与案例分析

代码如下: package BoxPack01;public class Box {private int milk;private boolean state false;public synchronized void put(int milk){if (state){try {wait();} catch (InterruptedException e) {e.printStackTrace();}}this.milk milk;System.out.println("送奶…

毕业4年年薪200万是怎样的一种体验?

之前的一篇文章提到过自己毕业4年&#xff0c;年薪就超过了200万。最近有很多读者问我是怎么实现的&#xff0c;过程中有哪些经验可以分享。说实话&#xff0c;这个话题不太想写&#xff0c;毕竟有炫耀嫌疑。不过问的人多了&#xff0c;发现大家对这个话题还是很关心。另外&…

自动控制原理第二版王建辉_王建辉自动控制原理配套题库名校考研真题课后答案资料课后习题章节题库模拟试题...

王建辉《自动控制原理》配套题库【名校考研真题&#xff0b;课后习题&#xff0b;章节题库&#xff0b;模拟试题】第一部分 名校考研真题 第1章 自动控制系统的基本概念 第2章 自动控制系统的数学模型 第3章 自动控制系统的时域分析 第4章 根轨迹法 第5章 频率法 第…

FluentAspects -- 基于 Fluent API 的 Aop

FluentAspects -- 基于 Fluent API 的 AopIntro上次我们做了一个简单的 AOP 实现示例&#xff0c;但是实现起来主要是基于 Attribute 来做的&#xff0c;对于代码的侵入性太强&#xff0c;于是尝试实现基于 Fluent API 的方式来做 AOP 。抽象 InterceptorResolver原来获取方法执…

2k2实用球员_nba2kol2操作技巧大全,nba2kol2平民球星阵容搭配。

NBA2KOL2手机版是一款专门针对酷爱打篮球的朋友打造的NBA正版篮球题材体育竞技类手游&#xff0c;熟悉篮球的朋友想必都知道&#xff0c;每年在圣诞节期间&#xff0c;NBA都会安排几场重量级的比赛&#xff0c;最近更是宣布了由利拉德和米切尔两位球星代言的NBA2KOL2手游终于在…

[Java网络编程基础]InetAddress的使用

代码如下: package InetAddressPack;import java.net.InetAddress; import java.net.UnknownHostException;public class InetAddressDemo {public static void main(String[] args) throws UnknownHostException { // InetAddress address InetAddress.getByName(&qu…

文件夹复制 覆盖_软网应用:U盘即插即复制

虽然现在网盘非常普及&#xff0c;但是对于一些重要文件的同步&#xff0c;很多朋友仍然在使用U盘进行同步。常规的方法是在A电脑将文件复制到U盘&#xff0c;然后在B电脑插入U盘&#xff0c;再将需要同步的文件复制到B电脑。这种操作不仅效率低&#xff0c;而且容易漏掉文件。…

面向接口编程,你考虑过性能吗?

大家在平时开发中大多都会遵循接口编程&#xff0c;这样就可以方便实现依赖注入也方便实现多态等各种小技巧&#xff0c;但这种是以牺牲性能为代价换取代码的灵活性&#xff0c;万物皆有阴阳&#xff0c;看你的应用场景进行取舍。一&#xff1a;背景1. 缘由在项目的性能改造中&…

python resample函数_python时序分析之重采集(resample)

接着上一回说到的时序分析&#xff0c;上一回主要是学习了datetime库和pandas.to_datetime模块。今天我们要学习的是resample&#xff0c;这一讲的内容很多&#xff0c;也有很多有意思的东西。老规矩&#xff0c;用到的资料来源于pandas.DataFrame.resample - pandas 0.24.2 do…

[Java网络编程]UDP通信程序练习

代码如下: package UdpPracticePack;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException;pub…