我们正在推出一个新的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 util,输入类型并不那么重要。

我知道对API进行AJAX调用的JavaScript客户端可能会喜欢JSON输入,以使他们的工作更轻松。


当前回答

您可能需要查看RFC 6570。这个URI模板规范展示了url如何包含参数的许多示例。

其他回答

将值列表作为URL参数传递的标准方法是重复它们:

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

大多数服务器代码将其解释为一个值列表,尽管许多服务器有单个值的简化,因此您可能需要查看。

带分隔符的值也可以。

如果你需要向服务器发送JSON,我不喜欢在URL中看到它(这是一种不同的格式)。具体来说,url有大小限制(理论上没有限制,但实际上是这样)。

我见过一些人用rest完成复杂查询的方法分为两步:

POST您的查询需求,接收回一个ID(本质上是创建一个搜索条件资源) 获取搜索,引用上面的ID 如果需要,可以选择删除查询需求,但是注意这些需求是可重用的。

第一个例子:

一个正常的乘积查找应该是这样的

http://our.api.com/product/1

所以我认为最好的做法是由你来做这件事

http://our.api.com/Product/101404,7267261

第二个案例

使用查询字符串参数进行搜索-就像这样。我会倾向于用AND和OR来组合术语,而不是使用[]。

附:这可能是主观的,所以做你觉得舒服的事情。

将数据放在url中的原因是链接可以粘贴到站点上/在用户之间共享。如果这不是一个问题,无论如何使用JSON/ POST代替。

编辑:经过反思,我认为这种方法适合具有复合键的实体,但不适用于多个实体的查询。

您可能需要查看RFC 6570。这个URI模板规范展示了url如何包含参数的许多示例。

我会支持nategood的回答,因为它是完整的,它似乎满足了你的需要。尽管如此,我还是想补充一个关于以这种方式识别多个(1个或更多)资源的评论:

http://our.api.com/Product/101404,7267261

在这样做时,你:

使客户端复杂化 迫使他们将你的响应解释为一个数组,如果我提出以下请求:http://our.api.com/Product/101404,这对我来说是违反直觉的

创建冗余api 用一个API获取所有产品,上面的API获取1个或多个产品。因为出于用户体验的考虑,你不应该向用户显示超过1页的详细信息,我认为超过1个ID是没有用的,纯粹是用来过滤产品的。

这可能不是什么问题,但是您要么必须自己在服务器端通过返回单个实体(通过验证您的响应是否包含一个或多个实体)来处理这个问题,要么让客户端管理它。

例子

我想从《神奇》订购一本书。我确切地知道这是哪本书,当我导航恐怖书籍时,我在列表中看到它:

10000条惊人的线,0个惊人的测试 神奇怪物的回归 让我们复制令人惊叹的代码 结局的惊人开端

在选择第二本书后,我被重定向到一个详细介绍列表中书籍部分的页面:

--------------------------------------------
Book #1
--------------------------------------------
    Title: The return of the amazing monster
    Summary:
    Pages:
    Publisher:
--------------------------------------------

还是在一页里只给我这本书的全部细节?

---------------------------------
The return of the amazing monster
---------------------------------
Summary:
Pages:
Publisher:
---------------------------------

我的意见

我建议在获取该资源的详细信息时,当保证惟一性时,在路径变量中使用ID。例如,下面的api提供了获取特定资源详细信息的多种方法(假设产品有唯一的ID,该产品的规范有唯一的名称,并且您可以自顶向下导航):

/products/{id}
/products/{id}/specs/{name}

当您需要多个资源时,我建议从更大的集合中筛选。同样的例子:

/products?ids=

当然,这是我的意见,因为它不是强加的。

第一:

我认为有两种方法

http://our.api.com/Product/<id>:如果你只想要一条记录

http://our.api.com/Product:如果你想要所有的记录

http://our.api.com/Product/<id1>,<id2>:正如James建议的那样,可以作为一个选项,因为Product标记后面的内容是一个参数

或者我最喜欢的是:

您可以使用RestFul WS的Hypermedia作为应用程序状态的引擎(HATEOAS)属性,并调用http://our.api.com/Product,该调用应该返回http://our.api.com/Product/<id>的等效url,并在此之后调用它们。

第二个

当你必须对url调用进行查询时。我建议再次使用HATEOAS。

1)给http://our.api.com/term/pumas/productType/clothing/color/black打个get电话

2)给http://our.api.com/term/pumas/productType/clothing,bags/color/black,red打个get电话

3)(使用HATEOAS)做一个得到调用' http://our.api.com/term/pumas/productType/ ->接收url所有服装可能的url ->调用那些你想要的(服装和包)->接收可能的颜色url ->调用那些你想要的