Proposal: Adding `RequestBehaviour`s to Malibu
codeOfRobin opened this issue · comments
Hey!
I've been reading about RequestBehaviour
recently and I think it'd be a great addition to Malibu, especially for things like Logging, NetworkActivityIndicator
s, authentication, caching etc.
Here's what the protocol looks like
protocol RequestBehavior {
func beforeSend()
func afterSuccess(result: Any)
func afterFailure(error: Error)
func adapt(_ request: URLRequest) -> URLRequest
}
// default implementations
extension RequestBehavior {
func beforeSend() {
}
func afterSuccess(result: Any) {
}
func afterFailure(error: Error) {
}
func adapt(_ request: URLRequest) -> URLRequest {
return request
}
}
And Auth can be implemented as follows:
struct TokenAuthBehaviour: RequestBehavior {
let token: String
func adapt(_ request: URLRequest) -> URLRequest {
var copy = request
var headers = copy.allHTTPHeaderFields ?? [:]
headers["Authorization"] = "Bearer \(token)"
copy.allHTTPHeaderFields = headers
return copy
}
}
struct CustomAuthBehaviour: RequestBehavior {
let key: String
let value: String
func adapt(_ request: URLRequest) -> URLRequest {
var copy = request
var headers = copy.allHTTPHeaderFields ?? [:]
headers[key] = value
copy.allHTTPHeaderFields = headers
return copy
}
}
struct CustomAuthBehaviour: RequestBehavior {
let key: String
let value: String
func adapt(_ request: URLRequest) -> URLRequest {
var copy = request
var headers = copy.allHTTPHeaderFields ?? [:]
headers[key] = value
copy.allHTTPHeaderFields = headers
return copy
}
}
There's other examples in the blog post, but this would be an excellent starting point (Logging could be in both before
and after
function calls, for example)
PS: Discussed this with @vadymmarkov on Twitter recently: https://twitter.com/vadymmarkov/status/956075029736894465
Another advantage to this approach is, you can compose Request Behaviours, making Malibu incredibly explicit!
struct CombinedRequestBehavior: RequestBehavior {
let behaviors: [RequestBehavior]
func adapt(_ request: URLRequest) -> URLRequest {
return behaviors.reduce(request) { (req, behaviour) in
return behaviour.adapt(req)
}
}
func beforeSend() {
behaviors.forEach({ $0.beforeSend() })
}
func afterSuccess(result: Any) {
behaviors.forEach({ $0.afterSuccess(result: result) })
}
func afterFailure(error: Error) {
behaviors.forEach({ $0.afterFailure(error: error) })
}
}
I think it would be a great addition to the library. What are your thoughts @onmyway133 @zenangst ?
@codeOfRobin @vadymmarkov Good idea. I see Malibu has customisation points where we can configure request already, but this is a nice refactoring around it.
I'll start working on some changes. Thank you for the feedback guys!
Hey folks! So sorry I’ve not been able to give it much thought over the past week + (Been dealing with some work stuff). Will get to this tomorrow 👍
Hey @vadymmarkov I've been considering retaining the beforeEach
and preProcessRequest
semantics in the RequestBehaviour protocol. Could you check this out and tell me what you think: codeOfRobin@51c6036
I think it should work @codeOfRobin