API 的 URL 设计
我正在为我们的后端开发私有 api。
我有一些具有关联的集合。
每个集合都可以被请求、分页,您还可以请求关联并对该关联进行分页。
我们不确定要使用哪种 URL 设计...我们正在考虑:
/users.json?per_page=10&association=parts,auditions&parts_per_page=5&auditions_per_page=5
/users.json?per_page=10&association[]=parts&association[]=auditions&parts_per_page=5&auditions_per_page =10
- 试镜&parts_per_page=5&auditions_per_page=10
/users.json?per_page=10&association[试镜] =true&association[parts][per_page]=5
你觉得怎么样?你会选择哪一个?为什么 ?其中之一看起来不像有效的网址方案吗?
谢谢 !
I'm working on a private apis for our backend.
I have collections that have associations.
Each collection can be requested, paginated, you can also ask for the associations and paginate this associations.
We're not sure about which URL design to use ... we're thinking about :
/users.json?per_page=10&association=parts,auditions&parts_per_page=5&auditions_per_page=5
/users.json?per_page=10&association[]=parts&association[]=auditions&parts_per_page=5&auditions_per_page=10
/users.json?per_page=10&association[auditions]=true&association[parts][per_page]=5
What do you think ? which one would you chosse ? why ? is one of this not looking like valid url schemes ?
Thanks !
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我的答案:
/users.json
。 HTTP 针对大颗粒超媒体传输进行了优化;缓存是其中的一个重要部分,上面给出的 URI 方案都不是非常适合缓存的。例如,Squid 是一种流行的 HTTP 缓存,默认情况下不会缓存任何具有查询字符串的 URL。此外,许多客户端甚至服务器和中介以未定义的顺序生成和使用查询字符串参数;即,“?a=3&b=5”可以任意改写为“?b=5&a=3”。然而,对于 HTTP 缓存来说,顺序很重要,即使两个页面具有相同的内容,它们也会被单独缓存。当您添加参数时,这个问题会呈指数级增长。
您应该设计您的资源(及其表示形式),以通过两种相反但互补的技术来利用缓存:
在您的情况下,步骤 1 意味着将关联和部分组合到“用户”表示中,而客户端没有任何选项来配置哪些关联和数量。这将允许您积极地缓存单个响应表示,而不会由于所有查询字符串选项而导致响应组合爆炸而使您(及其)缓存超载。
步骤 2 意味着将
/users.json
分成单独的“用户”实体,每个实体都有一个“关联”资源和一个“部件”资源。所以/users/{id}
和/users/{id}/associations
和/users/{id}/parts
。然后,“/users”资源返回指向各个“/users/{id}”资源的超链接数组,并且每个“/users/{id}”表示都包含指向其关联和部分的超链接(该部分更具延展性- -直接将关联和部分嵌入到用户资源中可能更适合您的应用程序)这将允许您积极地缓存每个“需要的”资源的响应,而无需缓存整个数据库,然后您的用户会尖叫“。但这是网络流量的 10 倍!”对此,您平静地回答,“不,这是网络流量的 1/10,因为所请求的资源十分之九已经位于您的客户端(浏览器)缓存中(并且当它们不是,它是服务器计算资源的 1/10,因为它们位于服务器端缓存中,当它们也不存在时,我们可以避免在服务器上使用智能缓存。”
当然,如果每天都有一百万新访问者访问
/users
资源,那么您的优化路径可能会有所不同。但根据您的示例 URI 方案,情况似乎并非如此。My answer:
/users.json
. HTTP is optimized for large-grain hypermedia transfer; caching is a big part of this, and none of the URI schemes given above are very cache-friendly.Squid, for example, is a popular HTTP cache that by default will not cache any URL that has a querystring. In addition, many clients and even servers and intermediaries generate and consume query string parameters in an undefined order; that is, "?a=3&b=5" can be arbitrarily rewritten as "?b=5&a=3". However, for HTTP caching, the order matters, and the two pages will be cached separately even though they have the same content. As you add parameters, this problem increases exponentially.
You should design your resources (and their representations) to take advantage of caching by two opposing but complementary techniques:
In your case, step 1 implies combining associations and parts into the "users" representation, without any option for the client to configure which ones and how many. That will allow you to aggressively cache the single response representation without overloading your (and their) caches with a combinatorial explosion of responses due to all the querystring options.
Step 2 implies separating
/users.json
into separate "user" entities, each with an "associations" resource and a "parts" resource. So/users/{id}
and/users/{id}/associations
and/users/{id}/parts
. The "/users" resource then returns an array of hyperlinks to the individual "/users/{id}" resources, and each "/users/{id}` representation contains hyperlinks to its associations and parts (that part is more malleable--it might fit your application better to embed the associations and parts into the user resource directly). That will allow you to aggressively cache the response for each "in demand" resource without having to cache your whole database.Then your users will scream "but that's 10 times the network traffic!" To which you calmly respond, "no, that's 1/10th the network traffic, because 9 times out of 10 the requested resources are already sitting in your client-side (browser) cache (and when they're not, it's 1/10th the server's computational resources since they're sitting in a server-side cache, and when they're not there either, we avoid stampeding with a smart cache on the server)."
Of course, if the
/users
resource is something a million new visitors hit every day, then your optimization path might be different. But it doesn't seem so based on your example URI schemes.restful-url 标签下有很多有用的帖子。
一些有用的帖子:
REST API URL 必须像这样吗?
使用 URI 作为参数的最佳实践REST 调用中的参数值。
如何创建不带动词的 REST URL?
There are a lot of useful posts under the restful-url tag.
Some useful posts:
Do REST API URLs have to look like this?
Best practices on using URIs as parameter value in REST calls.
How to create REST URL's without verbs?
我会选择第一个。我不喜欢在网址上看到 [] 符号,恕我直言,这会让客户端更难使用和理解。一些更改作为建议。
1)由于关联似乎是一个数组,请更改关联(复数,如果我是对的并且它是一个数组)
2)您还可以尝试放置默认的 per_page 和可选的,甚至聚合,例如 per_page_parts_auditions 而不是同时使用 per_page_parts 和 per_page_auditions。如果你的 API 被设计为公共的,我不会这样做,因为它更容易使用,但更难理解,但正如你发布的那样,它是一个私有的......应该是避免复制的好方法。
I would go for the 1st one. I don't like to see the [] notation on the url, IMHO it makes harder for the client to both use and understand. A few changes as suggestions.
1) As association seems to be an array, change for associations (plural, if I am right and it is an array)
2) You can also try to put a default per_page and an optional one, even aggregating, something like per_page_parts_auditions instead of using both per_page_parts and per_page_auditions. I wouldn't do it if your API was designed to be public, since it makes easier to use but harder to understand, but as you posted it is a private one.. should be a good way to avoid replication.