REST API最佳实践:路由设计

3
我想知道在创建涉及订单资源的REST API时,以下情况最佳实践是什么:
1. 获取数据库中的所有订单。(这显然不是一个实际的场景,仅供了解目的)
2. 通过订单ID获取订单。
3. 通过订单ID获取单个订单。
• 是否可以使用单个GET路线处理所有这些情况?
• 还是应该为这些情况设置不同的路线?
非常感谢任何帮助!(如果有关系,则使用Express JS框架)
2个回答

3

RESTful API使用HTTP方法作为动词。这意味着同一个端点可以用来获取订单列表和创建新订单;或者获取一个特定的订单,更新它甚至删除它。

考虑到这一点,您可以设计您的API结构如下:

GET       /orders        // To get a list of all orders
GET       /orders/:id    // To get information about a specific order

这将帮助您轻松地添加更多的方法,而不必改变API设计:

POST     /orders         // To create a new order
PUT      /orders/:id     // To update that specific order
DELETE   /orders/:id     // To delete it

如果您想在端点上添加搜索功能,使用查询字符串是非常常见的方法。以下是一些示例:

GET   /orders?email=john@example.org  // To retrieve all orders from that customer
GET   /orders?limit=10                // To retrieve only 10 hits per results
GET   /orders?limit=10&total=99.99    // To retrieve top 10 orders with a total of 99.99

您可以添加专用搜索参数以按ID返回订单(如所请求),但这并不像您已经可以使用端点/orders/:id按ID查询一样常见。您可能考虑避免额外的请求,但总的来说,性能提升相当低 - 除非按ID检索多个命中对于您的应用程序至关重要。


3
一个GET路由可以用于所有这些场景吗?
您可以使用一个路由来处理所有这些场景:
GET /orders                              // get all
GET /orders?id=409,5678,2987             // get these orders by id
GET /orders?id=9463                      // get this order by id
GET /orders?person=jackwelch             // get orders for this person
GET /orders?company=aaWidget             // get orders for this company 

这在很大程度上取决于设计意见。通常情况下,我倾向于尽可能少地使用不同的URL形式,并在合适且不感觉过于牵强的情况下重载相同的路由以处理不同的输入。但最终,这是一种基于对需要支持的查询总体情况和最可能的使用方式的理解而做出的判断。此外,请记住,添加新订单时应使用POST,修改现有订单时应使用PUT,删除订单时应使用DELETE。
POST   /orders                    // create new order, data in body of request
PUT    /orders/:id                // modify existing order, data in body of request
DELETE /orders/:id                // delete an order

因此,所有这些都可以通过一个名为/orders的URL结构对外界进行操作。在内部,它可能会被构建为几个不同的路由处理程序,以使处理代码更简单:
app.get("/orders", ...);         // handle order queries   (use req.query)
app.post("/orders", ...);        // create new order       (use req.body)
app.put("/orders/:id", ...);     // modify existing order  (use req.params.id and req.body)
app.delete("/orders/:id", ...);  // delete existing order  (use req.params.id)

这种结构的另一个好处是非常可扩展的。您只需添加其他查询字符串参数,而无需对结构进行整体更改甚至添加任何新的路由处理程序,就可以添加更多查询订单的方式。


感谢你的回答 @jfriend00。然而,在这种情况下,我们应该使用查询参数而不是普通参数。GET /orders/id/409,5678,2987 --> GET /orders?ids=409,5678,2987 - Zeeshan Shamsuddeen
RESTful APIs使用HTTP方法作为动词。因此,/orders/all不符合REST的要求。请参见下面的详细回应。 - Frenchcooc
@ZeeshanShamsuddeen - 经过更深入的思考,我更新了我的答案,并展示了Express路由处理程序的示例。 - jfriend00

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接