简体   繁体   English

REST API url设计

[英]REST API url design

I have a REST API that has a database with table with two columns, product_id and server_id , that it serves product_ids to specific servers which request the data(based on the server_id from table).我有一个 REST API 有一个带有两列的表的数据库, product_idserver_id ,它将 product_ids 提供给请求数据的特定服务器(基于表中的server_id )。 Let's say I have three servers with server_ids 1,2 and 3.假设我有三台服务器,server_ids 为 1,2 和 3。

My design is like this: /products/server_id/1 and with GET request I get json list of product_ids with server_id = 1, similarly /products/server_id/2 would output list of product_ids for server_id = 2 .我的设计是这样的: /products/server_id/1并且通过 GET 请求,我得到 json server_id = 1 的 product_ids 列表,类似/products/server_id/2将 output server_id = 2的 product_ids 列表。

Should I remove these routes and make a requirement to send POST request with instructions to receive product_ids for specific server_id in /products route only?我是否应该删除这些路由并要求发送带有指令的 POST 请求,以仅在/products路由中接收特定 server_id 的 product_ids?

For example sending payload {"server_id":1} would yield a response of list of product_ids for server_id = 1 .例如,发送有效负载{"server_id":1}将产生server_id = 1的 product_ids 列表的响应。

Should I remove these routes and make a requirement to send POST request with instructions to receive product_ids for specific server_id in /products route only?我是否应该删除这些路由并要求发送带有指令的 POST 请求,以仅在 /products 路由中接收特定 server_id 的 product_ids?

Not usually, no.通常不会,不会。

GET communicates to general purpose components that the semantics of the request message are effectively read only (see "safe" ). GET向通用组件传达请求消息的语义实际上是只读的(请参阅“安全” )。 That affordance alone makes a number of things possible;仅这种可供性就使许多事情成为可能; for instance, spiders can crawl and index your API, just as they would for a web site.例如,蜘蛛可以抓取和索引您的 API,就像它们对 web 站点一样。 User agents can "pre-fetch" resources, and so on.用户代理可以“预取”资源,等等。

All of that goes right out the window when you decide to use POST.当您决定使用 POST 时,所有这些都可以直接使用 window。

Furthermore, the URI itself serves a number of useful purposes - caches use the URI as the primary key for matching a request.此外,URI 本身有许多有用的用途——缓存使用 URI 作为匹配请求的主键。 Therefore we can reduce the load on the origin server by re-using representations have have been stored using a specific identifier.因此,我们可以通过重用已使用特定标识符存储的表示来减少源服务器的负载。 We can also perform magic like sticking that URI into an email message, without the context of any specific HTTP request, and the receiver of the message will be able to GET that identifier and fetch the resource we intend.我们还可以执行魔术,例如将该 URI 粘贴到 email 消息中,而无需任何特定 HTTP 请求的上下文,并且消息的接收者将能够获取该标识符并获取我们想要的资源。

Again, we lose all of that when the identifying information is in the request payload, rather than in the identifier metadata where it belongs.同样,当识别信息在请求有效负载中而不是在它所属的标识符元数据中时,我们会丢失所有这些信息。

That said, we sometimes do use the payload for identifying information, as a work around: for example, if we need so much identifying information that we start seeing 414 URI Too Long responses, then we may need to change our interaction protocol to use a POST request with the identifying information in the payload (losing, as above, the advantages of using GET).也就是说,我们有时确实使用有效负载来识别信息,作为一种解决方法:例如,如果我们需要太多的识别信息以至于我们开始看到414 URI Too Long响应,那么我们可能需要更改我们的交互协议以使用带有有效载荷中的识别信息的 POST 请求(如上所述,失去了使用 GET 的优势)。

An online example of this might be something like an HTML validator, that accepts a candidate document and returns a representation of the problems found.这方面的在线示例可能类似于 HTML 验证器,它接受候选文档并返回发现问题的表示。 That's effectively a read only action, but in the general case an HTML document is too long to comfortably fit in the target-uri of an HTTP request.这实际上是一个只读操作,但在一般情况下,HTML 文档太长,无法轻松放入 HTTP 请求的目标 uri。

So we punt.所以我们踢。

In a hypermedia api , like those used on the world wide web, we can get away with it, because the HTTP method to use is provided by the server as part of the metadata of the form itself.超媒体 api中,就像在世界范围内使用的 web 一样,我们可以摆脱它,因为 HTTP 使用的元数据方法是由服务器作为其自身形式的一部分提供的。 You as the client don't need to know the server's preferred semantics, you just need to know how to process the form data.您作为客户端不需要知道服务器的首选语义,您只需要知道如何处理表单数据。

For instance, as I type this answer into my browser, I don't need to know what the target URI is, or what HTTP method is going to be used, because the browser already knows what to do (based on the HTML and whatever scripts are running "on demand").例如,当我在浏览器中输入这个答案时,我不需要知道目标 URI 是什么,或者将使用什么 HTTP 方法,因为浏览器已经知道要做什么(基于 HTML 等等脚本正在“按需”运行)。

In REST APIs, POST requests should only be used in order to create new resource, so in order to retrieve data from server, the best practice is to perform a GET request.在 REST API 中,POST 请求只能用于创建新资源,因此为了从服务器检索数据,最佳实践是执行 GET 请求。

If you want to load products 1,2,4,8 on server 9 for example, you can use this kind of request:例如,如果你想在服务器 9 上加载产品 1、2、4、8,你可以使用这种请求:

GET https://website/servers/9/products/1,2,4,8

On server side, if products value contains a coma separated list, then return an array with all results, if not return just an array with only one item in order to keep consistency between calls.在服务器端,如果 products 值包含一个逗号分隔的列表,则返回一个包含所有结果的数组,如果不返回一个只有一项的数组,以保持调用之间的一致性。

In case you need to get all products, you can keep only the following url:如果您需要获得所有产品,您只能保留以下 url:

GET https://website/servers/9/products

As there is no id provided in products parameter, then the server should return all existing products for requested server parameter.由于 products 参数中没有提供 id,因此服务器应为请求的服务器参数返回所有现有产品。

Note: in case of big amount of results, they must by paginated.注意:如果结果量大,必须分页。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM