Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/adonisjs/core/llms.txt

Use this file to discover all available pages before exploring further.

Routing in AdonisJS allows you to map HTTP requests to specific handlers. Routes are typically defined in the start/routes.ts file.

Defining routes

Import the router service and define routes using HTTP method helpers:
import router from '@adonisjs/core/services/router'

// GET request
router.get('/users', () => {
  return { users: [] }
})

// POST request
router.post('/users', ({ request }) => {
  const body = request.all()
  return { created: true }
})

// Other HTTP methods
router.put('/users/:id', () => {})
router.patch('/users/:id', () => {})
router.delete('/users/:id', () => {})

Route parameters

Define dynamic segments in your routes using the :param syntax:
// Single parameter
router.get('/users/:id', ({ params }) => {
  return { user: { id: params.id } }
})

// Multiple parameters
router.get('/posts/:id/:slug', ({ params }) => {
  return { id: params.id, slug: params.slug }
})

// Optional parameters
router.get('/articles/:id/:slug?', ({ params }) => {
  // slug is optional
  return { id: params.id, slug: params.slug }
})

// Wildcard parameters
router.get('/files/:directory/*', ({ params }) => {
  // Matches /files/docs/guide/intro.md
  return { directory: params.directory, wildcard: params['*'] }
})

Named routes

Assign names to routes for easier URL generation:
router
  .get('/users/:id', ({ params }) => {})
  .as('users.show')

router
  .post('/users', ({ request }) => {})
  .as('users.store')

// Generate URL from route name
const url = router.makeUrl('users.show', { id: 1 })
// Returns: /users/1

Route handlers

Routes can use different types of handlers:

Closure handlers

router.get('/hello', ({ response }) => {
  return response.json({ message: 'Hello' })
})

Controller references

// Using controller string reference
router.get('/users', '#controllers/users_controller.index')

// Using controller array reference
import UsersController from '#controllers/users_controller'
router.get('/users', [UsersController, 'index'])

// Using lazy-loaded controller
router.get('/posts', [
  () => import('#controllers/posts_controller'),
  'index'
])

Render a view

// Directly render a view with data
router.on('/welcome').render('welcome', { username: 'virk' })

Redirect

// Redirect to another URL
router.on('/blog').redirect('/articles')

// Redirect to a named route
router.on('/old-path').redirectToRoute('new.route', { id: 1 })

Route groups

Group routes to apply common configuration:
router.group(() => {
  router.get('/posts', '#controllers/posts_controller.index')
  router.post('/posts', '#controllers/posts_controller.store')
  router.get('/posts/:id', '#controllers/posts_controller.show')
})
  .prefix('/api/v1')        // All routes prefixed with /api/v1
  .middleware(['auth'])     // Apply auth middleware to all routes
  .as('api.v1')            // Prefix all route names with api.v1

Nested groups

router.group(() => {
  // Public routes
  router.get('/posts', '#controllers/posts_controller.index')
  
  // Protected routes
  router.group(() => {
    router.post('/posts', '#controllers/posts_controller.store')
    router.delete('/posts/:id', '#controllers/posts_controller.destroy')
  }).middleware(['auth'])
  
}).prefix('/api')

Route middleware

Apply middleware to individual routes:
router
  .get('/dashboard', '#controllers/dashboard_controller.index')
  .use(middleware.auth())

// Multiple middleware
router
  .get('/admin', '#controllers/admin_controller.index')
  .use([middleware.auth(), middleware.admin()])

Route domains

Restrict routes to specific domains:
router
  .get('/articles', '#controllers/articles_controller.index')
  .domain('blog.adonisjs.com')

router
  .get('/articles/:id', '#controllers/articles_controller.show')
  .domain('blog.adonisjs.com')

Resourceful routes

Create RESTful routes for a resource:
import router from '@adonisjs/core/services/router'

router.resource('posts', '#controllers/posts_controller')
This creates the following routes:
MethodURLHandlerName
GET/postsindexposts.index
GET/posts/createcreateposts.create
POST/postsstoreposts.store
GET/posts/:idshowposts.show
GET/posts/:id/editeditposts.edit
PUT/PATCH/posts/:idupdateposts.update
DELETE/posts/:iddestroyposts.destroy

API resources

For APIs, exclude the create and edit routes:
router.resource('posts', '#controllers/posts_controller')
  .apiOnly()

Filtering resource routes

// Only create specific routes
router.resource('posts', '#controllers/posts_controller')
  .only(['index', 'show', 'store'])

// Exclude specific routes
router.resource('posts', '#controllers/posts_controller')
  .except(['create', 'edit'])

Listing routes

View all registered routes using the Ace command:
node ace list:routes
This displays a formatted table with all routes, their methods, patterns, handlers, and middleware.

TypeScript types

Get type-safe route parameters:
import type { InferRouteParams } from '@adonisjs/core/types/http'

router.get('/posts/:id/:slug', ({ params }) => {
  // params is typed as { id: string, slug: string }
  return { id: params.id, slug: params.slug }
})

// Extract route params type
type Params = InferRouteParams<'/posts/:id/:slug'>
// { id: string, slug: string }

Build docs developers (and LLMs) love