内容简介:【51CTO.com快译】众所周知,我们设计API的目标往往是要通过我们的服务,为用户提供一定的功能。虽然HTTP和URL资源都允许数据流进行一定程度的基本交互,但是它们在面对其他特定需求时,往往会让您的API显得力不从心。在此,我们以分页为例,即:如果某个数据库中存放着上百万篇的文章,那么我们很可能无法在单次响应中,将每一篇文章都发送给客户。针对此类需求,业界提出了参数化(parametrization)的解决方法。
【51CTO.com快译】
众所周知,我们设计API的目标往往是要通过我们的服务,为用户提供一定的功能。虽然HTTP和URL资源都允许数据流进行一定程度的基本交互,但是它们在面对其他特定需求时,往往会让您的API显得力不从心。在此,我们以分页为例,即:如果某个数据库中存放着上百万篇的文章,那么我们很可能无法在单次响应中,将每一篇文章都发送给客户。针对此类需求,业界提出了参数化(parametrization)的解决方法。
什么是参数化?
通常而言,参数化是一种请求配置。在编程语言中,我们可以通过某个函数来请求对应的返回值。如果一个函数不带任何参数,那么我们将无法直接去影响它的返回值。
API也是如此,尤其是那些无状态的REST API。毕竟,所有REST的交互都是无状态的。也就是说,每个请求都会包含那些方便连接器理解该请求的所有信息,而且它们与之前的任何请求都无关。
在实际应用中,我们有许多种方法可以向HTTP请求中添加参数,其中包括:查询字符串,POST、PUT报文,各种PATCH请求、以及标头(header)。它们各自都有自己的用例和规则。
那么,添加所有参数数据的最简单方法,就是将所有内容放入报文内。在具体应用中,每个端点都会用到POST方法,而许多API也会把所有的参数放置在报文中。长此以往,传统的API里积累了越来越多的参数,以致于它们不再适合查询字符串等操作。显然,我们应当避免在设计API时此类极端情况的发生。
添加何种参数?
就REST而言,作为API查询语言的GraphQL,为用户提供了满足数据查询的运行时。那么,我们是否应当添加那些在HTTP规范中已经标准化的标头字段类来作为参数(请参见:http://www.rfcreader.com/#rfc2616_line4589)呢?
- 如果使用Accept标头,我们可以定义响应所采用的格式或媒体类型。我们既可以使用它来告知API所需要的JSON或XML,又可以使用它来获取API的版本(请参见: https://www.moesif.com/blog/technical/api-design/Best-Practices-for-Versioning-REST-and-GraphQL-APIs/?utm_source=dzone&utm_medium=paid&utm_campaign=placed%20article&utm_term=rest%20api%20design%20best%20practices%20for%20parameters%20and%20query%20string%20usage )。
- 而如果使用Cache-Control标头,我们则可以防止API发送带有no-cache的缓存响应,且无需使用查询字符串作为cache buster(?cb=)。
- 当然,授权也可以被视为一种参数。根据API在实际授权过程中的详细信息,是否通过授权,来产生不同种类的响应。因此,HTTP也为此定义了一个授权类型的标头(请参见: http://www.rfcreader.com/#rfc2616_line4922 )。
在我们了解了各种默认标头字段后,下面我们来讨论是否应该为自己的参数创建一个自定义的标头字段,或者将其放入URL的查询字符串中。
何时该使用查询字符串?
如果我们已获悉待添加的参数不属于默认的标头字段,且并不敏感,那么我们就应当通过查看查询字符串,以确认是否合适。在查询字符串的时候,有个
因此,查询字符串的主要用例便是过滤,它会着重过滤搜索和分页这两种特殊的情况。有关此方面的详细讨论,请参见: https://www.moesif.com/blog/technical/api-design/REST-API-Design-Filtering-Sorting-and-Pagination/?utm_source=dzone&utm_medium=paid&utm_campaign=placed%20article&utm_term=rest%20api%20design%20best%20practices%20for%20parameters%20and%20query%20string%20usage 。不过,正如针对Web表单的目的所示,它可以被用于不同类型的参数。而RESTful API可以将POST或PUT请求与报文一起使用,以实现将表单数据发送给服务器。
我们来看一个有关嵌套表示(nested representation)的参数示例。默认情况下,我们需要返回文章的普通表示形式(plain representation)。当我们将?withComments查询字符串添加到端点时,?withComments会以普通表示形式返回某篇文章的评论,而且仅需要一个请求即可。至于此类参数是应该被放在自定义的标头中,还是查询字符串里,则主要取决于开发人员的个人经验与偏好。
根据HTTP的规范陈述(请参见: http://www.rfcreader.com/#rfc2616_line1761 ):标头字段可以被视为函数的参数。不过,将查询字符串添加到URL中会明显比创建客户端标头,要更快、更显著。实际上,这些字段充当了请求修饰符,其语义等同于编程语言在方法调用中的参数。
在实际应用中,您会发现:在所有端点上保持相同的参数更适合于标头。例如:身份验证令牌可以由每个请求所发送。而那些高度动态的参数(尤其是仅对少数几个端点有效的参数)则应该被放在查询字符串中。例如:每个端点的过滤器参数都会有所不同。
数组和映射参数
对于开发人员而言,他们可能会经常碰到的一个问题是:如何处理查询字符串中的数组参数?例如,我们可能碰到需要搜索多个名称的需求场景。而通常的解决方案是:使用方括号。如下列代码所示:
不过,HTTP的规范指出:由IPv6 [RFC3513]或更高版本标识的主机通过将IP方括号(“[”和“]”)来区分。这是URI语法中唯一允许使用方括号字符的地方。
我们在许多HTTP服务器和客户端的实现场景中,都应当牢记上述规范。当然,为了简便起见,我们可以采用“多次使用一个参数名称”的另一种解决方案。如下列代码所示:
该方法虽然有效,但是它会导致开发人员体验上的下降。通常情况下,客户端只会使用类似于地图(map-like)的数据结构。而该结构在被添加到URL中之前,会进行简单的字符串转换。而这恰恰会导致后续的数值被覆盖。可见,在发送请求之前,我们需要进行更加复杂的转换。
与此同时,也有人会采用另一种方法:使用“,”字符来分隔数值,直接在URL中出现未经编码的字符。如下列代码所示:
而对于那些类似地图的数据结构,我们也可以使用无需编码的“.”字符。如下列代码所示:
另外,您还可以对整个查询字符串进行URL编码(请参见: https://en.wikipedia.org/wiki/Percent-encoding ),以便直接使用任何想要的字符或格式。不过值得一提的是,这同样也会大幅降低开发人员的使用体验。
何时不该使用查询字符串?
在实际应用中,由于查询字符串往往是URL的一部分。而那些隐藏在客户端和API之间的攻击者(如:中间人,MIM)则可以轻而易举地读取到我们的URL,因此我们不应该简单地将诸如密码之类的敏感数据,直接放入查询字符串之中。
虽然大多数HTTP客户端在URL中都会允许使用五位数(five-figure)长度的字符,但是如果我们未能全面设计和考虑URL的整体长度,那么开发人员在调试此类字符串时,往往也会经历各种繁琐和不便。
当然,由于我们能够将任何内容都定义为资源,因此我们有时候完全可以使用POST端点,来进行大量参数的调用与传递,进而将报文中的所有数据都发送给API。
可见,为了避免向查询字符串中那些具有多个参数的资源发送GET请求,进而导致冗长且不可识别的URL产生,我们可以设计出诸如搜索类型的资源,根据API的需求,来缓存各种计算的结果。同时,我们还可以向/searches端点发布新的请求。而该请求会将我们的搜索相关配置与参数保存在报文之中。通过返回一个搜索ID,以便我们使用它来获取搜索的结果。
总结
作为API设计人员或架构师,我们所追求的优秀实践,实际上就是要找出API的最理想使用方式,以及最简单的实现用例。综上所述,我们建议您注意如下两个方面:
- 从一开始就能够借助Moesif(人工智能API服务平台)之类的服务,着手分析自身API的使用模式。
- 嵌套式资源虽然可以提高URL的可读性,但是如果我们嵌套得太多的话,则会导致URL参数的冗长。因此,如果您发现自己创建了一个具有超大的查询字符串端点,那么我建议您最好从其中提取一部分子资源,放置到报文中作为参数发送出去。
原文标题:REST API Design Best Practices for Parameters and Query String Usage,作者:Kay Ploesser
【51CTO译稿,合作站点转载请注明原文译者和出处为51CTO.com】
【责任编辑:庞桂玉 TEL:(010)68476606】
以上所述就是小编给大家介绍的《REST API设计优秀实践之参数与查询的使用》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- JVM 参数最佳实践:元空间的初始大小和最大大小
- Spark Streaming调优参数及最佳实践深入剖析-Spark商业调优实战
- TypeScript 中的命名参数、可选参数、默认参数
- PXC状态参数与变量参数
- 更加灵活的参数校验,Spring-boot自定义参数校验注解
- AI新人必看 | 参数和超参数还分不清楚吗?
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
微信小程序运营与推广完全自学手册
王洪波 / 电子工业出版社 / 2018-6 / 59
本书是运营管理方面的书籍,将小程序的运营推广问题置千小程序的整个运营管理体系中来谈,主要讲述小程序的定位规划、营销吸粉策略、评估优化这三大方面的内容,这三方面的内容之间是三位一体、密切相关的。 书中通过列举丰富且具有代表性的小程序实际案例来向读者提供些可行的运营推广办法。案例涉及美食类、电商类、旅游类、媒体类等小程序,可供多个行业的小程序运营者参考借鉴。 书中所提供的各种小程序营销策略......一起来看看 《微信小程序运营与推广完全自学手册》 这本书的介绍吧!
HTML 编码/解码
HTML 编码/解码
HSV CMYK 转换工具
HSV CMYK互换工具