-
Notifications
You must be signed in to change notification settings - Fork 321
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
Add configuration (for extractors and middleware) #5
Comments
So as I'm working on #8 I figured I would add my own thoughts around this. When it configuration, different web frameworks have different ways of going about it. The two chief ways I can think of are:
There are pros and cons to both of them, but I think the most flexible solution would be to have a set of defaults, which are overridden by values parsed from the environment and these can be further overridden by programatic configuration. I think this is a good idea because for someone who just wants to set up a quick service, they will have sane defaults to work with, while setting up configuration to be read from a file/environment will help make deployments flexible. On top of that, we can provide specific control over individual routes as presented by @aturon . |
I've tried to use typemap, but cloneable one yields forward compatibility warning regarding object safety.
|
How about we just have a config struct with a few fields to start with and wrap it in an Arc to be shared across? My reasoning is that for the most part configuration is for configuring the framework, so the number of knobs that a user can turn are limited. So we can have default values set up which are overridden with the parsed values from a config file/environment which can be further overridden programmatically using something like Just a thought. |
@tirr-c I experimented with the I'm not sure how this typemap will be shared internally within Tide though. |
I experimented with the |
I have an idea that doesn't require global states or typemaps, but is somewhat less flexible -- using Configuration can be set and retrieved with typed configuration items (like the sample code above.) Those items should implement trait ConfigurationItem: Serialize + Deserialize + Default {
const NAME: &'static str;
} When new endpoint is established, configuration of the parent router will be cloned into the endpoint. This is easier to implement, but it makes configuration and resource declaration depend on their order, like A positive side effect of this approach is that it makes implementing configuration files a trivial job, as we can use Serde for serializing and deserializing. |
@tirr-c Interesting thought! I'm a little worried though that it'd impose some overhead that should be avoidable. Looking more closely at the warning for In other words, I bet that we could roll our own version of trait CloneAny: Send + Sync {
fn clone_any(&self) -> Box<dyn CloneAny>;
}
impl Clone for Box<dyn CloneAny> {
fn clone(&self) -> Self {
self.clone_any()
}
} @tirr-c do you want to take another stab at using |
My bad I did not see the comment on #100 , I agree having this API to tweak the configuration per endpoint is definitely more flexible. So if I'm understanding this right, it means that the configuration will be accessible on the |
So I was thinking about how to share configuration with middleware and was considering something along the lines of this: The impl<Data, F> Middleware<Data> for F
where
F: Send + Sync + Fn(RequestContext<Data>) -> FutureObj<Response>,
{
fn handle<'a>(&'a self, ctx: RequestContext<'a, Data>, config: TypeMap<dyn CloneAny>) -> FutureObj<'a, Response> {
(self)(ctx)
}
} Definitely a rough design, but what do you guys think? |
@bIgBV I think configuration can be wrapped in @aturon I've experimented with your trait design (with some tweaks) and it's promising! However I'm afraid we can't use existing |
@tirr-c I was considering |
@tirr-c PR looks really good! |
Most extractors and middleware should be configurable. But that presents some challenges:
One approach for solving these problems is to use a typemap for configuration, allowing extractors and middleware to provide their knobs as public types that can be installed into the map. This map would then be built as part of constructing the router:
(Note: the
nest
example uses the feature proposed here).Note that this functionality could be implemented using middleware and the
extensions
part of the request, but that would mean the configuration is constructed fresh during request handling, rather than when the app is constructed.Let's reach consensus on a design, and then implement this!
The text was updated successfully, but these errors were encountered: