@@ -252,9 +252,10 @@ pub fn (mut app App) controller_get_user_by_id() vweb.Result {
252252```
253253### Middleware
254254
255- V haven't a well defined middleware.
256- For now, you can use ` before_request() ` . This method called before every request.
257- Probably you can use it for check user session cookie or add header
255+ Vweb has different kinds of middleware.
256+ The ` before_request() ` method is always called before every request before any
257+ other middleware is processed. You could use it to check user session cookies or to add a header.
258+
258259** Example:**
259260
260261``` v ignore
@@ -263,24 +264,117 @@ pub fn (mut app App) before_request() {
263264}
264265```
265266
267+ Middleware functions can be passed directly when creating an App instance and is
268+ executed when the url starts with the defined key.
269+
270+ In the following example, if a user navigates to ` /path/to/test ` the middleware
271+ is executed in the following order: ` middleware_func ` , ` other_func ` , ` global_middleware ` .
272+ The middleware is executed in the same order as they are defined and if any function in
273+ the chain returns ` false ` the propogation is stopped.
274+
275+ ** Example:**
276+ ``` v
277+ module main
278+
279+ import vweb
280+
281+ struct App {
282+ vweb.Context
283+ middlewares map[string][]vweb.Middleware
284+ }
285+
286+ fn new_app() &App {
287+ mut app := &App{
288+ middlewares: {
289+ // chaining is allowed, middleware will be evaluated in order
290+ '/path/to/': [middleware_func, other_func]
291+ '/': [global_middleware]
292+ }
293+ }
294+
295+ // do stuff with app
296+ // ...
297+ return app
298+ }
299+
300+ fn middleware_func(mut ctx vweb.Context) bool {
301+ // ...
302+ return true
303+ }
304+
305+ fn other_func(mut ctx vweb.Context) bool {
306+ // ...
307+ return true
308+ }
309+
310+ fn global_middleware(mut ctx vweb.Context) bool {
311+ // ...
312+ return true
313+ }
314+ ```
315+
316+ Middleware functions will be of type ` vweb.Middleware ` and are not methods of App,
317+ so they could also be imported from other modules.
318+ ``` v ignore
319+ pub type Middleware = fn (mut Context) bool
320+ ```
321+
322+ Middleware can also be added to route specific functions via attributes.
323+
324+ ** Example:**
325+ ``` v ignore
326+ [middleware: check_auth]
327+ ['/admin/data']
328+ pub fn (mut app App) admin() vweb.Result {
329+ // ...
330+ }
331+
332+ // check_auth is a method of App, so we don't need to pass the context as parameter.
333+ pub fn (mut app App) check_auth () bool {
334+ // ...
335+ return true
336+ }
337+ ```
338+ For now you can only add 1 middleware to a route specific function via attributes.
339+
266340### Redirect
267341
268342Used when you want be redirected to an url
343+
269344** Examples:**
270345
271346``` v ignore
272347pub fn (mut app App) before_request() {
273- app.user_id = app.get_cookie('id') or { app.redirect('/') }
348+ app.user_id = app.get_cookie('id') or { app.redirect('/') }
274349}
275350```
276351
277352``` v ignore
278353['/articles'; get]
279354pub fn (mut app App) articles() vweb.Result {
280- if !app.token {
281- app.redirect('/login')
282- }
283- return app.text("patatoes")
355+ if !app.token {
356+ app.redirect('/login')
357+ }
358+ return app.text('patatoes')
359+ }
360+ ```
361+
362+ You can also combine middleware and redirect.
363+
364+ ** Example:**
365+
366+ ``` v ignore
367+ [middleware: with_auth]
368+ ['/admin/secret']
369+ pub fn (mut app App) admin_secret() vweb.Result {
370+ // this code should never be reached
371+ return app.text('secret')
372+ }
373+
374+ ['/redirect']
375+ pub fn (mut app App) with_auth() bool {
376+ app.redirect('/auth/login')
377+ return false
284378}
285379```
286380
0 commit comments