REST API 最佳实践:如何接受参数值列表作为输入 [英] REST API Best practice: How to accept list of parameter values as input

查看:27
本文介绍了REST API 最佳实践:如何接受参数值列表作为输入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在推出一个新的 REST API,我想要一些关于我们应该如何格式化输入参数的最佳实践的社区意见:

现在,我们的 API 非常以 JSON 为中心(仅返回 JSON).关于我们是否想要/需要返回 XML 的争论是一个单独的问题.

由于我们的 API 输出是以 JSON 为中心的,因此我们一直走在一条道路上,我们的输入有点以 JSON 为中心,我一直认为这对某些人来说可能很方便,但总的来说很奇怪.

例如,要获取一些产品详细信息,我们目前可以同时提取多个产品:

http://our.api.com/Product?id=["101404","7267261"]

我们是否应该将其简化为:

http://our.api.com/Product?id=101404,7267261

或者是否方便使用 JSON 输入?更痛苦?

我们可能希望同时接受这两种风格,但这种灵活性实际上是否会导致更多的混乱和头痛(可维护性、文档等)?

更复杂的情况是我们想要提供更复杂的输入.例如,如果我们想在搜索中允许多个过滤器:

http://our.api.com/Search?term=pumas&filters={"productType":["Clothing","Bags"],"color":["Black","Red"]}

我们不一定要将过滤器类型(例如 productType 和 color)作为这样的请求名称:

http://our.api.com/Search?term=pumas&productType=["Clothing","Bags"]&color=["Black","Red"]

因为我们想将所有过滤器输入组合在一起.

最后,这真的重要吗?可能有太多的 JSON 实用程序,以至于输入类型并不那么重要.

我知道我们的 JavaScript 客户对 API 进行 AJAX 调用可能会喜欢 JSON 输入,让他们的生活更轻松.

解决方案

退一步

首先,REST 将 URI 描述为通用唯一 ID.太多的人陷入了 URI 的结构以及哪些 URI 比其他 URI 更安静"的问题.这个论点就像说将某人命名为鲍勃"比命名他为乔"更好一样荒谬——这两个名字都完成了识别一个人"的工作. URI 只不过是一个 普遍唯一名称.

所以在 REST 看来,争论 ?id=["101404","7267261"] 是否比 ?id=101404,7267261 更安静Product101404,7267261 有点徒劳.

现在,话虽如此,很多时候 URI 的构造方式通常可以作为 RESTful 服务中其他问题的良好指标.您的 URI 和一般问题中有几个危险信号.

建议

  1. 同一资源的多个 URI 和 Content-Location

    <块引用>

    我们可能希望同时接受这两种风格,但这种灵活性实际上是否会导致更多的混乱和头痛(可维护性、文档等)?

    URI 标识资源.每个资源都应该有一个规范的 URI.这并不意味着您不能让两个 URI 指向同一个资源但是有明确定义的方法可以做到这一点.如果您决定同时使用 JSON 和基于列表的格式(或任何其他格式),您需要决定这些格式中的哪一种是主要的规范 URI.对指向同一资源"的其他 URI 的所有响应都应包含 Content-Location 标题.

    坚持名称类比,拥有多个 URI 就像拥有人的昵称.这是完全可以接受的,而且通常很方便,但是如果我使用昵称,我可能仍然想知道他们的全名——指代那个人的官方"方式.这样,当有人提到某人的全名Nichloas Telsa"时,我知道他们在谈论我称为Nick"的同一个人.

  2. 在您的 URI 中搜索"

    <块引用>

    更复杂的情况是我们想要提供更复杂的输入.例如,如果我们想在搜索中允许多个过滤器...

    我的一般经验法则是,如果您的 URI 包含动词,则可能表明某事已关闭.URI 标识一个资源,但是它们不应该表明我们正在对该资源做什么.这就是 HTTP 的工作,或者用宁静的术语来说,就是我们的统一接口".

    为了打破名字类比,在 URI 中使用动词就像在您想与某人互动时更改某人的名字.如果我与 Bob 互动,当我想和 Bob 打招呼时,Bob 的名字不会变成BobHi".同样,当我们要搜索"产品时,我们的 URI 结构不应从/Product/..."更改为/Search/...".

回答你最初的问题

  1. 关于 ["101404","7267261"]101404,7267261:我的建议是为了简单起见避免使用 JSON 语法(即不要不要求您的用户在您真的不需要时进行 URL 编码).它会让你的 API 更有用一点.更好的是,正如其他人所建议的那样,使用标准的 application/x-www-form-urlencoded 格式,因为它可能是您的最终用户最熟悉的(例如 ?id[]=101404&id[]=7267261).它可能不是漂亮",但漂亮的 URI 并不一定意味着可用的 URI.然而,重申我最初的观点,最终在谈到 REST 时,这并不重要.不要太在意它.

  2. 您的复杂搜索 URI 示例的解决方法与您的产品示例非常相似.我建议再次使用 application/x-www-form-urlencoded 格式,因为它已经是许多人熟悉的标准.另外,我建议将两者合并.

您的 URI...

/Search?term=pumas&filters={"productType":["Clothing","Bags"],"color":["Black","Red"]}

URI 编码后的 URI...

/Search?term=pumas&filters=%7B%22productType%22%3A%5B%22Clothing%22%2C%22Bags%22%5D%2C%22color%22%3A%5B%22Black%22%2C%22Red%22%5D%7D

可以转化为...

/Product?term=pumas&productType[]=Clothing&productType[]=Bags&color[]=Black&color[]=Red

除了避免对 URL 编码的要求并使事情看起来更标准之外,它还使 API 同质化了一点.用户知道,如果他们想要检索产品或产品列表(在 RESTful 术语中两者都被视为单个资源"),他们会对 /Product/... URI 感兴趣.>

We are launching a new REST API and I wanted some community input on best practices around how we should have input parameters formatted:

Right now, our API is very JSON-centric (only returns JSON). The debate of whether we want/need to return XML is a separate issue.

As our API output is JSON centric, we have been going down a path where our inputs are a bit JSON centric and I've been thinking that may be convenient for some but weird in general.

For example, to get a few product details where multiple products can be pulled at once we currently have:

http://our.api.com/Product?id=["101404","7267261"]

Should we simplify this as:

http://our.api.com/Product?id=101404,7267261

Or is having JSON input handy? More of a pain?

We may want to accept both styles but does that flexibility actually cause more confusion and head aches (maintainability, documentation, etc.)?

A more complex case is when we want to offer more complex inputs. For example, if we want to allow multiple filters on search:

http://our.api.com/Search?term=pumas&filters={"productType":["Clothing","Bags"],"color":["Black","Red"]}

We don't necessarily want to put the filter types (e.g. productType and color) as request names like this:

http://our.api.com/Search?term=pumas&productType=["Clothing","Bags"]&color=["Black","Red"]

Because we wanted to group all filter input together.

In the end, does this really matter? It may be likely that there are so many JSON utils out there that the input type just doesn't matter that much.

I know our JavaScript clients making AJAX calls to the API may appreciate the JSON inputs to make their life easier.

解决方案

A Step Back

First and foremost, REST describes a URI as a universally unique ID. Far too many people get caught up on the structure of URIs and which URIs are more "restful" than others. This argument is as ludicrous as saying naming someone "Bob" is better than naming him "Joe" – both names get the job of "identifying a person" done. A URI is nothing more than a universally unique name.

So in REST's eyes arguing about whether ?id=["101404","7267261"] is more restful than ?id=101404,7267261 or Product101404,7267261 is somewhat futile.

Now, having said that, many times how URIs are constructed can usually serve as a good indicator for other issues in a RESTful service. There are a couple of red flags in your URIs and question in general.

Suggestions

  1. Multiple URIs for the same resource and Content-Location

    We may want to accept both styles but does that flexibility actually cause more confusion and head aches (maintainability, documentation, etc.)?

    URIs identify resources. Each resource should have one canonical URI. This does not mean that you can't have two URIs point to the same resource but there are well defined ways to go about doing it. If you do decide to use both the JSON and list based formats (or any other format) you need to decide which of these formats is the main canonical URI. All responses to other URIs that point to the same "resource" should include the Content-Location header.

    Sticking with the name analogy, having multiple URIs is like having nicknames for people. It is perfectly acceptable and often times quite handy, however if I'm using a nickname I still probably want to know their full name – the "official" way to refer to that person. This way when someone mentions someone by their full name, "Nichloas Telsa", I know they are talking about the same person I refer to as "Nick".

  2. "Search" in your URI

    A more complex case is when we want to offer more complex inputs. For example, if we want to allow multiple filters on search...

    A general rule of thumb of mine is, if your URI contains a verb, it may be an indication that something is off. URI's identify a resource, however they should not indicate what we're doing to that resource. That's the job of HTTP or in restful terms, our "uniform interface".

    To beat the name analogy dead, using a verb in a URI is like changing someone's name when you want to interact with them. If I'm interacting with Bob, Bob's name doesn't become "BobHi" when I want to say Hi to him. Similarly, when we want to "search" Products, our URI structure shouldn't change from "/Product/..." to "/Search/...".

Answering Your Initial Question

  1. Regarding ["101404","7267261"] vs 101404,7267261: My suggestion here is to avoid the JSON syntax for simplicity's sake (i.e. don't require your users do URL encoding when you don't really have to). It will make your API a tad more usable. Better yet, as others have recommended, go with the standard application/x-www-form-urlencoded format as it will probably be most familiar to your end users (e.g. ?id[]=101404&id[]=7267261). It may not be "pretty", but Pretty URIs does not necessary mean Usable URIs. However, to reiterate my initial point though, ultimately when speaking about REST, it doesn't matter. Don't dwell too heavily on it.

  2. Your complex search URI example can be solved in very much the same way as your product example. I would recommend going the application/x-www-form-urlencoded format again as it is already a standard that many are familiar with. Also, I would recommend merging the two.

Your URI...

/Search?term=pumas&filters={"productType":["Clothing","Bags"],"color":["Black","Red"]}    

Your URI after being URI encoded...

/Search?term=pumas&filters=%7B%22productType%22%3A%5B%22Clothing%22%2C%22Bags%22%5D%2C%22color%22%3A%5B%22Black%22%2C%22Red%22%5D%7D

Can be transformed to...

/Product?term=pumas&productType[]=Clothing&productType[]=Bags&color[]=Black&color[]=Red

Aside from avoiding the requirement of URL encoding and making things look a bit more standard, it now homogenizes the API a bit. The user knows that if they want to retrieve a Product or List of Products (both are considered a single "resource" in RESTful terms), they are interested in /Product/... URIs.

这篇关于REST API 最佳实践:如何接受参数值列表作为输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆