【问题标题】:REST API best practise for routes路由的 REST API 最佳实践
【发布时间】:2020-04-23 19:02:54
【问题描述】:

当订单是资源时,我想知道为以下场景创建 REST API 时的最佳做法是什么:

  1. 获取数据库中的所有订单。 (肯定不是实际场景,仅供理解)
  2. 按订单 ID 获取订单。
  3. 按订单 ID 获取单个订单

• 单个 GET 路由能否用于所有这些场景?

• 或者我们应该为这些场景设置单独的路线?

任何帮助将不胜感激! (如果重要,使用 Express JS 框架)

【问题讨论】:

    标签: rest api express server


    【解决方案1】:

    单个 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 的情况下实际使用查询参数而不是普通参数
    • RESTful API 使用 HTTP 方法作为动词。因此,/orders/all 对 REST 不友好。请参阅下面的详细回复
    • @ZeeshanShamsuddeen - 经过更多思考,我更新了我的答案并展示了 Express 路由处理程序的示例。
    【解决方案2】:

    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 检索多个命中对您的应用程序至关重要。

    【讨论】:

      猜你喜欢
      • 2013-10-23
      • 2017-11-04
      • 2020-05-29
      • 1970-01-01
      • 2018-07-09
      • 2021-09-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多