Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: Adding RequestBehaviours to Malibu #88

Open
codeOfRobin opened this issue Jan 24, 2018 · 7 comments
Open

Proposal: Adding RequestBehaviours to Malibu #88

codeOfRobin opened this issue Jan 24, 2018 · 7 comments

Comments

@codeOfRobin
Copy link

Hey!

I've been reading about RequestBehaviour recently and I think it'd be a great addition to Malibu, especially for things like Logging, NetworkActivityIndicators, 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

@codeOfRobin codeOfRobin changed the title Add RequestBehaviours to Malibu Proposal: Adding RequestBehaviours to Malibu Jan 24, 2018
@codeOfRobin
Copy link
Author

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) })
	}
}

@vadymmarkov
Copy link
Owner

I think it would be a great addition to the library. What are your thoughts @onmyway133 @zenangst ?

@onmyway133
Copy link
Contributor

@codeOfRobin @vadymmarkov Good idea. I see Malibu has customisation points where we can configure request already, but this is a nice refactoring around it.

@codeOfRobin
Copy link
Author

I'll start working on some changes. Thank you for the feedback guys!

@codeOfRobin
Copy link
Author

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 👍

@codeOfRobin
Copy link
Author

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

@vadymmarkov
Copy link
Owner

I think it should work @codeOfRobin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants