Configure request method for a Siesta resource

妖精的绣舞 提交于 2019-12-03 09:15:52

Siesta’s load() and loadIfNeeded() are only for GET requests.

Why? Those Siesta methods are build on the assumption that they don’t have side effects, that their results can be cached, and that they are safe to call zero, one, or many times. In HTTP, this is the contract of GET. However, POST, PUT, etc do no make any such promise; each request can have a separate effect, and they are thus dangerous to call either repeatedly or optionally.

To make requests using POST, PUT, and DELETE, use Resource.request(…):

loginResource.request(.post)

(See the section on requests in the Siesta user guide for more info on how request(…) differs from load(…).)


Why isn’t there a separate setting to, for example, make a resource be a “POST resource?” Because the REST approach is that /foo is the name of a logical thing — a resource — and GET /foo and PUT /foo are different actions on it, one that retrieves its state and one that changes it. This is not merely a matter of aesthetic purity; the strong promises of GET are closely tied to it.

If your API is completely non-REST-shaped, Siesta may not be a good fit for it. However, you may also be able to write a NetworkProvider that translates REST-shaped requests into your API’s own structure, letting Siesta essentially treat it as a REST API.


APIs usually don’t take passwords in a query string (which is what withParam(…) does), but rather in a post body.

(Aside: if your API does take a password in a query string, you probably don’t want it to. Passwords in query strings are easily leak into insecure places — log files, for example. But you know your API, and I realize you often have to work with what you’ve got!)

In the likely event that your API does take a password in a POST body instead of a query string, you can do this:

// 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])

If you really want Siesta to cache the result of your auth call as if it had been a GET request, you can use Resource.load(using:):

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

This is useful if you want to publish your auth credentials within the app using ResourceObservers, for example. The more common approach is to use an onSuccess hook to grab the credentials once and update the service configuration, but load(using:) can be a helpful alternative in some situations.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!