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
vweb: middleware implementation #17730
Conversation
If you want something to be shared across all sessions, mark it with the |
I've added some tests. And fixed post requests. |
I can see that my new test file is failing in the CI and that the other vweb tests are skipped in |
It only fails on windows, not sure what the issue is
the error is not printed |
Great job by the way! This is a great addition. |
Good work!! |
It turns out windows runs a weird resolution algorithm when using |
you can use
for such code blocks |
You successfully got deep into vweb, good job! :) Perhaps when you have time you could help me out with a similar feature I've been trying to do for a while. Something similar to "controllers" in MVC. Right now we can only have one App struct per Would be nice to have |
Sure sounds interesting! I think it would be a good addition to make vweb more powerful. You could for example generate an admin page (controller) to visually interact with your models/data. Will think about it. |
@Casper64 @medvednikov I have implemented a similar function in a web framework, currently using the |
Implementation of middleware for vweb, inspired by the syntax of discussion #15187 and code in pull request #12961.
Why
Was playing around with vweb and couldn't find a solution for per route middleware. Currently any middleware is only added before every request and it becomes difficult if you only want middleware for specific routes. It doesn't give much freedom or extensability with other (future) modules.
Usage
Middleware functions can be passed directly when creating an App instance.
Middleware functions will be of type
vweb.Middleware
and are not methods of App, so they could also be imported from other modules.Middleware can also be added to route specific functions via attributes e.g.:
For now you can only add 1 middleware to a route specific function. But this could be changed easily if the attributes syntax changes ( see discussion #17715 )
Example
Explanation
Context.before_request
is always executed first before any other middleware.When visiting
"/admin/secrets"
the path starts with"/admin/"
so afterContext.before_request
other_func1
andother_func2
are executed. The function itself also has the attribute[middleware: check_auth]
soApp.check_auth
is executed.If any middleware returns
false
the propogation is stopped.In this example we can see that everything until
App.check_auth
returns true, so we expect that 0, 1, 2, 3 are printed, but not "Secrets page".Indeed the method
App.secrets
is not executed. But we can see an html page, becauseApp.check_auth
callsApp.redirect
before returning false, thus sending an http response to the client.middleware_early
returns false, so we expect to see a ":(" instead of the html page.Middleware also works for dynamic routes.
Drawbacks (?)
For each request the middlewares map is cloned to each new App, like
db
. Feels a bit hacky.Limited comptime error checking(?)
Cool
It was really fun to dive deeper into the workings of V! I've learned a lot about the language.