为 Siesta 资源配置请求方法

Configure request method for a Siesta resource

我有这个 api,其中登录通过 post 工作,而大多数其他请求使用 get。现在我正在使用午睡将登录 url 定义为资源。

func login(username: String, password: String) -> Resource {
    return self.resource("login").withParam("username", username).withParam("password", password);
}

问题是,当我在此资源上使用 .loadIfNeeded() 时,它会执行一个获取请求,但这不起作用,因为它需要一个 post 请求。

现在我知道 .decorateRequests 的存在,但我不确定如何使用它来使我的登录资源使用 post 作为请求方法。

提前致谢,

彼得

Siesta 的 load()loadIfNeeded() 仅适用于 GET 请求。

为什么?这些 Siesta 方法建立在以下假设之上:它们没有副作用,它们的结果可以被缓存,并且它们可以安全地调用零次、一次或多次。在 HTTP 中,这是 GET 的约定。但是,POST、PUT 等不做任何此类承诺;每个请求都可以有单独的效果,因此重复或可选地调用它们是危险的。

要使用 POST、PUT 和 DELETE 发出请求,请使用 Resource.request(…):

loginResource.request(.post)

(有关 request(…)load(…) 的不同之处的更多信息,请参阅 the section on requests in the Siesta user guide。)


为什么没有单独的设置,例如,使资源成为“POST 资源?”因为 REST 方法是 /foo 是逻辑事物的名称——资源——而 GET /fooPUT /foo 是对它的不同操作,一个检索它的状态,一个改变它.这不仅仅是审美纯度的问题; GET 的强大承诺与它密切相关。

如果您的 API 完全是 non-REST-shaped,午睡可能不适合。但是,您也可以编写一个 NetworkProvider 将 REST-shaped 请求转换为您的 API 自己的结构,让 Siesta 本质上将其视为 REST API。


APIs 通常不会在查询字符串中使用密码(withParam(…) 就是这样做的),而是在 post 正文中。

(另外:如果您的 API 确实在查询字符串中使用密码,您可能不希望它这样做。查询字符串中的密码很容易泄露到不安全的地方——例如日志文件。但是你知道你的 API,而且我知道你经常需要使用你所拥有的东西!)

如果您的 API 确实在 POST 正文而不是查询字符串中使用密码,您可以这样做:

// If it’s a JSON request
loginResource.request(.post, json: ["user": user, "password": pass])

// If it an HTML form encoded request
loginResource.request(.post, urlEncoded: ["user": user, "password": pass])

如果您真的希望 Siesta 缓存您的身份验证调用的结果,就好像它已经 是 GET 请求一样,您可以使用 Resource.load(using:):

authResource.load(using:
  authResource.request(
      .post, json: ["user": user, "password": pass]))

例如,如果您想使用 ResourceObservers 在应用程序中发布您的身份验证凭据,这将很有用。更常见的方法是使用 onSuccess 挂钩一次获取凭据并更新服务配置,但 load(using:) 在某些情况下可能是一种有用的替代方法。