-
Notifications
You must be signed in to change notification settings - Fork 120
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
Per-request middleware? (in RequestBuilder) #261
Comments
I think this is unlikely to happen - see Fishrock123#1, or rather, the discussion around it, since yes, it is technically possible even if less-than-pleasant. Since clients share underlying resources anyways, you should probably just clone your client, or use one if you aren't. |
If you are doing advanced usage already, you should probably not do this. It will always be less efficient somehow (even if that is just creating new memory for middleware to sit in). IMO, we should recommend using clients, and improve that story as much as possible. |
@Fishrock123 Thanks for taking time to answer! I agree that promoting client usage as much as possible is a good idea (although it's currently not clear from the docs, and the first block of code you see in the readme uses One example of a use case you've asked for would be more or less like this: you have a single client that holds connection pool, and your application makes multiple types/group of requests - e.g. A, B and C - where, say, you want to log requests A, and you also want to validate and log requests of type C in a different way, and requests B you don't care about. This would currently require you to either:
|
This will always be the best option, fwiw, even if per-RequestBuilder middleware becomes a thing. I do something like this for multiple base urls all over the place, e.g. in this code. Are you saying you have somewhere where you'd need different middleware for every endpoint? Or more like |
Neither really - say, there's a few dozen endpoints with the same base url, which form a number of groups that have to be handled differently middleware-wise (say, for example, half of them need to be logged, half of them need to be validated, half of them need to be serialized, etc - and these halves may overlap). Am I supposed to hold a few dozen clients and match them? This gets very clunky very fast. Another point is - disallowing per-request middleware makes it hard passing the RequestBuilder around in case your requests are built in multiple stages and not inside one function which has the client in scope, in case you also want endpoint-dependent middleware. There's |
Oof that's a fear I had of keeping |
Generally - yes, agreed; but not always :) Since |
Yeah - I am saying that pattern is probably problematic (abstraction leaking?) and you may want to try doing it the other way around. |
@Fishrock123 Yes, you're probably right, I'm not arguing here :) Just trying to present the thoughts of someone new to surf (but who's read some of its sources out of confusion!). Like, "hey, so RequestBuilder looks like a thing to build Request, that's a common builder pattern, I know it. But, hold on, it also holds a client.. sometimes, or sometimes it doesn't. And a client can also return a RequestBuilder which can build requests which are then tied to that client?. So... I want to inspect a request and it appears that I need to build a separate middleware type which I can... only attach it to the client, so does it mean I have to attach it before I start building the request, is that the only way to do it? So I have to clone it, am I doing it right? Is cloning expensive, does it depend on client type? And should I stop using RequestBuilder and just use mutable methods on Request, but then what's the point of that builder type in the first place? (goes off to read the source)" Out of curiosity (correct me if I'm wrong here) I've run a quick bench with the default client, creating a new client takes about 270us while cloning it is about 10-15us. Much faster and in most cases negligible, but in other cases 15us is too slow and a few orders of magnitude slower than pushing an object onto a vec. (unless you're using "pre-made clients" as we've discussed above, of course) |
If you want to be fast, you want to use a pre-made client. I am becoming more sympathetic to the idea here, but I also feel it may be due to an error in the overall API design. maybe that ship has sailed though... unsure. |
See #266 |
(somewhat related to #259)
Would be nice to be able to do something like
request_builder.with(my_middleware)
which would replace the client it holds with a version that has the given middleware pushed on the stack (using the default shared client as the base if needed).This would also make it possible to apply middleware to the default shared client on a per-request basis (which is arguably not the most efficient way to do so, but still):
The text was updated successfully, but these errors were encountered: