On this page
routing
introduction
routes are defined in the routes directory. dframework automatically discovers and loads every .js file in that directory at boot time without any manual imports. inside each route file you have access to the global Route facade which proxies directly to the internal router instance.
basic routes
the simplest route accepts a url path and a controller string pointing to the method that should handle it.
1// routes/web.js2import { Route } from 'dframework';3 4Route.get('/dashboard', 'app.IndexController@dashboard');5Route.post('/register', 'auth.AuthController@register');6Route.put('/profile', 'app.UserProfileController@update');7Route.delete('/session', 'auth.AuthController@logout');
available methods
the router supports four http verbs.
1Route.get(path, handler);2Route.post(path, handler);3Route.put(path, handler);4Route.delete(path, handler);
route parameters
dynamic url segments are prefixed with a colon. the router extracts and decodes these values and makes them available on req.params inside your controller.
1Route.get('/user/:id', 'app.IndexController@user');2Route.get('/admin/:entity/:id/edit', 'admin.AdminController@editForm');1// controllers/app/IndexController.js2export default class IndexController {3 async user(req) {4 const user = await User.find(req.params.id);5 return json({ user });6 }7}
named routes
you give a route a name by chaining .name() after its definition. named routes allow you to generate urls programmatically without hardcoding paths.
1Route.get('/dashboard', 'app.IndexController@dashboard').name('dashboard');2Route.get('/user/:id', 'app.IndexController@user').name('app.user.profile');to generate a url from a named route you use the global route() helper.
1const dashboardUrl = route('dashboard');2const profileUrl = route('app.user.profile', { id: 42 });
route groups
groups allow you to share attributes like prefixes and middleware across a set of routes without repeating yourself on every definition.
prefix
1Route.group({ prefix: '/faq' }, (faq) => {2 faq.get('/', 'app.IndexController@faq').name('app.faq');3 faq.get('/tos', 'app.IndexController@faq_tos').name('app.faq.tos');4 faq.get('/privacy', 'app.IndexController@faq_privacy').name('app.faq.privacy');5});
middleware
1Route.group({ middleware: ['AuthMiddleware@requireAuth'] }, (auth) => {2 auth.get('/home', 'app.HomeController@home').name('app.home');3 auth.get('/library', 'app.IndexController@library').name('app.library');4});
combined attributes
prefix and middleware can be used together in a single group definition.
1Route.group({ prefix: '/admin', middleware: ['AuthMiddleware@requireAuth', 'AdminMiddleware@requireAdmin'] }, (admin) => {2 admin.get('/', 'admin.AdminController@index').name('admin.index');3 admin.get('/:entity', 'admin.AdminController@list').name('admin.list');4 admin.post('/:entity', 'admin.AdminController@store').name('admin.store');5});groups can be nested. an inner group inherits all attributes of its parent and may add its own on top.
1Route.group({ middleware: ['AuthMiddleware@requireAuth'] }, (auth) => {2 auth.group({ prefix: '/api/preferences' }, (prefs) => {3 prefs.get('/', 'app.PreferencesController@index').name('api.preferences.index');4 prefs.put('/:key', 'app.PreferencesController@update').name('api.preferences.update');5 });6});
inline middleware chains
instead of a single controller string you can pass an array as the handler. the framework treats all entries before the last as middleware and the final entry as the controller.
1pair.post('/approve', ['AuthMiddleware@requireAuth', 'auth.AuthController@approvePost']).name('approve.post');you can also apply middleware to a single route without a group by calling .middleware().
1Route.middleware(authLimiter.middleware()).post('/register', 'auth.AuthController@register');
route modifiers
every route definition returns a chainable object that exposes several modifiers to control framework behavior on that specific route.
csrf
csrf verification is enabled by default on all post, put, and delete routes. you can disable it for a specific route by chaining .csrf(false).
1Route.post('/magic/:token', 'auth.AuthController@magicConsume').csrf(false);
shield
when the shield security system is active it validates incoming mutation requests. you can opt a route out by chaining .shield(false).
1Route.post('/magic/:token', 'auth.AuthController@magicConsume').shield(false);
log
request and response logging is automatic in the local environment. you can force logging for a specific route in production by chaining .log().
1Route.post('/api/playback/track', 'app.PlaybackController@get_track').name('api.playback.track').log();
views
the .views() modifier tells the route compiler exactly which view templates this route renders. during the production build the compiler analyzes those templates to determine what session data locale detection and body parsing the compiled handler actually needs. providing explicit view names is an optimization hint that removes ambiguity from the static analysis step.
1Route.get('/dashboard', 'app.IndexController@dashboard').name('dashboard').views(['app.home.index']);
profile
the .profile() modifier lets you override the behavior profile the compiler derives from its static analysis of the route. you pass an object whose keys replace the analyzed values. this is an advanced escape hatch for routes where the automatic analysis produces an incorrect or suboptimal compiled handler.
the available profile keys are:
needsSession: booleanneedsPreviousUrl: booleanneedsFlash: booleanneedsBody: booleanneedsLocale: booleanneedsAntiPeeping: booleanhasCsrf: booleanhasShield: boolean
1Route.get('/feed', 'app.FeedController@index').profile({ needsSession: true, needsFlash: true });
controller string syntax
controller strings follow the directory.ControllerName@method convention. the directory segment maps to a subdirectory inside controllers/. a controller at controllers/app/IndexController.js is referenced as app.IndexController@index. a controller at controllers/auth/AuthController.js is referenced as auth.AuthController@register.
1Route.get('/dashboard', 'app.IndexController@dashboard');2Route.post('/register', 'auth.AuthController@register');for controllers sitting directly in the controllers/ root with no subdirectory you omit the directory prefix entirely.
1Route.get('/locale/:locale', 'LocaleController@set');
multiple route files
you may split your routes across as many files as you like inside the routes directory. the framework loads all .js files it finds there automatically. the order of loading follows the filesystem sort order.
1// routes/web.js (http routes)2// routes/wire.js (socket routes)
