在 Vapor 3 中返回位置为 header 的 201(已创建)

Returning a 201 (Created) with location header in Vapor 3

我正在尝试使用 Vapor 3 实现 REST-ful API,我更愿意使用在其他 Web 框架中看起来相当标准的创建模式:我喜欢实体创建控制器 return 201 Created 响应状态,Location 响应 header 包含 newly-created 资源的完整 URL。

我能找到的所有 Vapor 3 文档都显示了一个创建模式,而不是 returns 200 OK 状态,并在响应 body 中包含完整资源。但我找不到任何使用 201 响应的示例,尽管根据我的经验,这往往是更标准的 REST-ful API 方法。

我发现我可以在我的控制器中手动创建一个 201 响应,我假设有一种方法可以在该响应中设置任意 headers。如果是这样,是否有一种方便的方法来获取我刚刚创建的资源的完整 URL,以便我可以在响应中设置 Location header?

我确定有一些方法可以 "brute force" 这得到我想要的东西,但我希望 Vapor 定义了一种惯用的方法来做到这一点,就像 Java 和 Rails 我使用过的框架提供。

由于您是手动创建响应,所以您是对的,添加任意 header 很简单。

我假设你遵循标准的 CRUD 路由结构,所以如果你有一个 User 模型,你有以下路由:

  • POST /users
  • GET /users/:user
  • PATCH /users/:user
  • DELETE /users/:user

这里重要的是我们知道获取用户的URL就是创建用户的URL加上用户的ID。如果是这种情况,我们可以像这样创建一个位置 header:

user.save(on: req).map { user in
    let http = HTTPResponse(...)

    let location = req.http.url.path + "/" + user.id.description
    http.headers.replaceOrAdd(name: "Location", value: location)

    return Response(http: http, container: req)
}