Moya: What is the difference between requestclosure and endpointclosure?

Created on 9 Sep 2016  路  14Comments  路  Source: Moya/Moya

What is the difference between requestclosure and endpointclosure? Are they technically the same thing? They look very similar.

What are the different circumstances in which on would utilize them?
Can they both be used together on the same provider?

The definition I'm getting from the following is that requestclosures sort of wrap around the endpoint? I'm trying to find a more concrete definition to distinguish the two. Thanks!

The next optional initializer parameter is requestClosure, which resolves an Endpoint to an actual NSURLRequest. Again, check out the Endpoints documentation for how and why you'd do this

Is there some sort of precedence that request closures follows after endpoint closures, or vice versa?

documentation question

Most helpful comment

Hey there! I'll do my best to help you distinguish them 馃槈

EndpointClosure defines how to map TargetType to Endpoint. RequestClosure on the other hand, resolves Endpoint into NSURLRequest (or Error if the request shouldn't be performed). You can use them both on the same provider and RequestClosure follows after EndpointClosure.

In the EndpointClosure you can customize endpoint's parameterEncoding, headers or additional parameters and more if you want. There you can setup things your API needs in the headers or parameters, that should go globally. You can also stub the statusCode so it returns errors instead of 200 for testing purposes.

Then, when you have the Endpoint created, there is that RequestClosure. You are moments before the request. Here you can change things that you want in NSURLRequest, but also you can perform asynchronous token fetch, and if it fails you can stop the request as well (and this is the place for it).

There is also great documentation about the topic here. If you find something hard to understand, you are more than welcome to make an issue or pull request if you know how to fix it.

Hope it helps! If you have more questions, let us know! 馃惣

All 14 comments

Hey there! I'll do my best to help you distinguish them 馃槈

EndpointClosure defines how to map TargetType to Endpoint. RequestClosure on the other hand, resolves Endpoint into NSURLRequest (or Error if the request shouldn't be performed). You can use them both on the same provider and RequestClosure follows after EndpointClosure.

In the EndpointClosure you can customize endpoint's parameterEncoding, headers or additional parameters and more if you want. There you can setup things your API needs in the headers or parameters, that should go globally. You can also stub the statusCode so it returns errors instead of 200 for testing purposes.

Then, when you have the Endpoint created, there is that RequestClosure. You are moments before the request. Here you can change things that you want in NSURLRequest, but also you can perform asynchronous token fetch, and if it fails you can stop the request as well (and this is the place for it).

There is also great documentation about the topic here. If you find something hard to understand, you are more than welcome to make an issue or pull request if you know how to fix it.

Hope it helps! If you have more questions, let us know! 馃惣

Great answer, @sunshinejr. @rlam3 let us know what else we can clarify, we're always looking for ways to improve our documentation!

@ashfurrow Would love to see more on authentication documentation using OAuth/JWT and how to store and mange tokens to be integrated with Moya.

Because checking if a token is expired and updating the token prior to firing off an authenticated request is a synchronous task. I would like to see a proper way for authenticated requests to be organized with the use of keychain libraries like Locksmith.swift to manage tokens.

Thanks!

Hi @rlam3, thanks for opening the issue. We actually have some auth-specific documentation here I wanted to make sure you were aware of; the request closure has been specifically designed with OAuth and other forms of asynchronous authentication in mind. If you have any suggestions on ways to improve our documentation, please send a pull request and we can take it from there.

@ashfurrow thanks for the pointers to the authentication/oauth posts. I'm still a bit stuck on the point on how to actually get moya refresh an access token prior to firing off another authenticated request.

I've been poking around the following code from eidolon and ello...

https://github.com/artsy/eidolon/blob/master/Kiosk/App/Networking/Networking.swift

https://github.com/ello/ello-ios/blob/master/Sources/Networking/ElloProvider.swift

I see some similarities but also many diffferences. For instance, they are using a state machine to deal with authenticated requests. But how is eidolon checking if the token is expired and updating the access_token on the client side?

I saw the following piece of code, but this doesn't require the user credentials to return the token...

https://github.com/artsy/eidolon/blob/master/Kiosk/App/Networking/Networking.swift#L51-L83

How is the access_token refreshed? Many Thanks!

You found the code that does the refreshing, further down that file you'll see the code that calls the fetching code: https://github.com/artsy/eidolon/blob/a7bb061c89cd4bed44d956b1376909ca0e72060b/Kiosk/App/Networking/Networking.swift#L87-L94

Basically, the XAppTokenRequest function's Observable always returns a valid token (whether it was a cached valid token, or a newly fetched token). Then we use flatMap to turn that Observable into one that represents the _actual_ network call we want to make. Does that make sense?

Hey @ashfurrow. I like that approach! I was thinking of something similar myself. I had a few of questions for you:

I assume you are using NSUserDefaults for persistence between app launches. That being said, I don't see a .synchronize() call anywhere, so are you just relying on the periodic automatic synchronization? It also looks like AppDelegate clears out the token values from user defaults at launch. If that is the case, then is using the defaults system as a on-disk cache useful at all? Is it just being used as an in-memory cache? If so, wouldn't you get the same effect by giving the XAppToken a static var to store an in-memory version of the current token? As much as I hate that sort of global state, it doesn't seem worse and is as testable as NSUserDefaults. Sorry if I am completely misunderstand the intention here. 馃槵

Also, could you point me to where in the code you inject the tokens into the requests? I'm really interested in using a similar pattern, but this is my first go around with Moya and that's one of the last pieces of the puzzle for me. Thanks!

Yup, don't need to worry about synchronizing NSUserDefaults manually, it does it for you. And worst case, it looses the token and just fetches a new one. We clear them out just for consistency's sake. NSUserDefaults is just a convenient place to put them. We inject the token here: https://github.com/artsy/eidolon/blob/a7bb061c89cd4bed44d956b1376909ca0e72060b/Kiosk/App/Networking/Networking.swift#L132

@ashfurrow Is XAppTokenRequest different from a normal acess_token? I'm a bit confused here. Or is XAppTokenRequest supposed to request back a new JWT?

We don't use a JWT in that app, but the principle is the same. That's where you would add any tokens as HTTP headers, or sign the request using Heimdall or whatever for OAuth.

@ashfurrow This may not be the right thread to ask but I'm a little confused on how to retrieve the auth token from the response headers and was hoping you'd be able to help me understand how to access it?

Good question; the response object contains the URLResponse which has the headers you can access.

Awww thank you! My problem was I had to cast response.response as? NSHTTPURLResponse before it allowed me to use the .allHeaderFields["..."] function on it

Cool! Sounds like your issue was resolved, so I'm going to close this. Please feel free to re-open if that's not the case, thanks again!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Tynox picture Tynox  路  3Comments

holysin picture holysin  路  3Comments

PlutusCat picture PlutusCat  路  3Comments

GurpalRajput picture GurpalRajput  路  3Comments

JianweiWangs picture JianweiWangs  路  3Comments