Replies: 0 comments 2 replies
-
|
Hi @Jeehut! Thanks for the discussion and feedback! I could definitely see some tweaking here. Maybe something like: let loginResponse = try await client.response(for: .login, as: LoginResponse.self).valueTo respond more directly to a few of your items:
I definitely agree that typed errors can be handy, but we're trying to follow Apple's lead here, which is to prefer throwing functions. Luckily I think you can extend
We looked to prior art here. In particular, I think
The client-level JSON decoder was actually added in this PR: We just need to cut a new version for it. As for |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
I just watched your latest episode and while I loved the whole idea of keeping your API client in sync with the server & how mocking is solved in
_URLRouting, I do have an issue with the API semantics of therequest(_:as:decoder:)method, see this screenshot:To me this feels wrong for the following reasons:
request(...)returns a request object similar toURLRequestor executes a request and returns some kind of response. This is a common issue with English words that can be a verb or a noun, as some APIs prefer describing the return type and others prefer describing the side effects (which is what you do here).asyncAPIs, Apple actually prefers describing the return type, see for example theURLSession.data(for:delegate)API or the freshMusicCatalogSearchRequest.response()API from MusicKit introduced during WWDC2021. So Apple platform developers might expect that this to return some kind ofRequestobject, likeNSManagedObject.fetchRequest().throwingwhich is fine for those who prefer throwing APIs, but in my own Twitter survey I learned that (at least in my bubble) more developers preferResultAPIs because we don't have precise error typing in Swift yet unless we returnResult.failureinstead of throwing. The cool thing about returningResultinstead of throwing is also, that users get a throwing API for free because they can just callget()on the Result.asnaming makes the function readrequest aswhich is not that bad, but still lacks some clarity in my opinion. It could be easily mixed up with the formatting of the body, for example, so some might try writingrequest(..., as: .json). In my own networking library I named that parameterdecodeBodyTowhich could fit here, too.decodercurrently needs to be provided with every single request, but it is very common to reuse one decoder for all request of a specific server. So much so, that I think the library should provide adefaultDecoderproperty on theURLRoutingClientlevel in my opinion. This could still be overridden when needed on a per-call basis.So putting all these changes together, I suggest to change the semantics of the
requestmethod from:To this:
Where the error type could look something like this:
The error type is just a quick and dirty suggestion, we could provide a more sophisticated error type covering all common error reasons to provide users with a more helpful explicit error type, something like my own
ApiErrortype but adjusted to this library.Would love to hear your thoughts!
Beta Was this translation helpful? Give feedback.
All reactions