2010-12-10 63 views
9

我正在为我们的后端使用私人API。
我有拥有关联的集合。
每个集合都可以请求分页,也可以请求关联并对这些关联进行分页。API的URL设计

我们不知道要使用哪个URL设计......我们正在考虑:

  • /users.json?per_page=10 &协会=零件,试镜& parts_per_page = 5 & auditions_per_page = 5

  • /users.json?per_page=10 &关联[] =份&关联[] =试镜& parts_per_page = 5 & auditions_per_page = 10

  • /users.json?per_page=10 &协会[试听] =真&协会[零件] [per_page] = 5

你觉得呢?你会选哪一个?为什么?这是不是看起来像有效的网址计划之一?

谢谢!

回答

14

我的回答:/users.json。 HTTP针对大粒度超媒体传输进行了优化;缓存是其中的重要组成部分,上面给出的任何URI方案都非常缓存友好。

例如,Squid是一个流行的HTTP缓存,默认情况下,它不会缓存任何具有查询字符串的URL。另外,许多客户端甚至服务器和中介都以未定义的顺序生成和使用查询字符串参数;也就是说,“a = 3 & b = 5”可以任意改写为“αb = 5 & a = 3”。但是,对于HTTP缓存,顺序很重要,即使它们具有相同的内容,这两个页面也会分开缓存。当你添加参数时,这个问题呈指数增长。

您应通过两个设计你的资源(和他们交涉),以充分利用高速缓存的对立而是相辅相成的技术:

  1. 组合分散,部分表示成更大的,统一表示,和
  2. 独立的大,沿着缓存边界(往往是事务性边界)统一表示为较小的表示,但通过超链接相关。

对于您的情况,第1步意味着将关联和零件组合成“用户”表示形式,没有任何客户端配置哪些和多少个选项的选项。这将允许您积极地缓存单个响应表示,而不会由于所有查询字符串选项而使您的(及其缓存)重载组合式爆炸式响应。

步骤2意味着将/users.json分隔成单独的“用户”实体,每个实体都具有“关联”资源和“部件”资源。所以/users/{id}/users/{id}/associations/users/{id}/parts。然后“/ users”资源返回一个超链接数组到每个“/ users/{id}”资源,并且每个“/ users/{id}”表示包含到其关联和部分的超链接(该部分更具可塑性 - - 它可能会更好地将您的应用程序嵌入到用户资源中直接嵌入到用户资源中),这将允许您积极缓存每个“需求”资源的响应,而不必缓存整个数据库。用户会尖叫“但是这是网络流量的10倍!”对此你冷静地回应,“不,这是网络流量的1/10,因为10次请求的资源中有9次已经位于客户端(浏览器)缓存(当它们不存在时,它是服务器计算资源的十分之一,因为它们坐在服务器端缓存中,并且当它们不在那里时,我们避免了令人讨厌的机智h服务器上的智能缓存)。“

当然,如果/users资源是每天新增访问者数百万,那么您的优化路径可能会有所不同。但它似乎不是基于您的示例URI方案。

+0

嘿fumanchu,感谢您的答复!我不明白为什么我的网址未针对缓存进行优化?这个调用不会在浏览器中完成,但可以在服务器端完成(我可以轻松地基于url + params进行缓存)。我不想为每个关联分开呼叫(这就是为什么我的API不完全安静),这将意味着多次调用以获取一些信息,我甚至不需要缓存... – Mike 2010-12-12 17:44:34

+0

我在里面添加了我的回复我的回答如上(斜体)。 – fumanchu 2010-12-13 18:14:31

+0

感谢您的帮助!很好的论点,你说服我=) – Mike 2010-12-14 13:27:17

3
+0

嘿马库斯,感谢您的后续工作,并将其标记为restful-url,我没有找到任何关于在API中使用数组的有用帖子。而且我不确定这个API可以被归类为一个安静的API,我们不想把所有东西都嵌套起来......否则为了从一个集合中获得2个关联,我们必须进行2次调用,而且我们并不想要那。 – Mike 2010-12-10 16:11:01

1

我会去的第一个1。我不喜欢在URL上看到[]符号,恕我直言,它使客户更难以使用和理解。建议的一些变化。

1)作为联想似乎是一个数组,变更为协会(复数,如果我是正确的,它是一个数组)

2)您也可以尝试把默认per_page和一个可选的一个,甚至是聚合,就像per_page_parts_auditions,而不是同时使用per_page_parts和per_page_auditions。我不会这样做,如果你的API被设计为公开的,因为它更容易使用但更难理解,但是因为你发布它是私有的。应该是避免复制的好方法。

+0

1 /同意(这是一个集合数组.. .. /基本上是sql关系)2 /已经有一个默认的per_page(你不需要定义它,但你可以 - 也有{association} _per_page默认我只是想告诉你一些用例),我不能真正使用per_page_parts_auditions,因为我只向你展示2个关联,但事实上还有很多,我有很多不同的集合(全都有不同的关联)。我们的{关联} _per_page参数是动态生成的。 – Mike 2010-12-10 16:25:24

+0

由于您的{关联} _per_page参数是动态生成的,因此无法将{association} _per_page和您的代码调用{关联} _per_page代码? – 2010-12-10 16:28:53

+0

对不起,我没有得到这最后一个问题,我已经要求{协会} _per_page .. – Mike 2010-12-12 19:53:42