Контроллеры
Пока маршрутов мало, код можно писать прямо в start/routes.ts. Но с ростом проекта файл разбухает. Контроллер — это класс, который собирает обработчики запросов одного раздела сайта, например статей блога. Каждый метод класса обрабатывает один маршрут.
Создание контроллера
node ace make:controller postsПоявится файл app/controllers/posts_controller.ts. Имя файла — во множественном числе и с окончанием _controller, имя класса — PostsController.
Метод контроллера
Добавьте в класс два метода:
// app/controllers/posts_controller.ts
import type { HttpContext } from '@adonisjs/core/http'
export default class PostsController {
async index({}: HttpContext) {
return 'Список статей'
}
async show({ params }: HttpContext) {
return `Статья номер ${params.id}`
}
}Каждый метод получает тот же объект контекста, что и функция в маршруте. Тип HttpContext подсказывает редактору, какие в нём есть поля. Пустая деструктуризация в index значит, что поля контекста этому методу пока не нужны.
Подключение к маршруту
В маршруте вместо функции указывают массив: контроллер и имя метода.
// start/routes.ts
import router from '@adonisjs/core/services/router'
const PostsController = () => import('#controllers/posts_controller')
router.get('/posts', [PostsController, 'index']).as('posts.index')
router.get('/posts/:id', [PostsController, 'show']).as('posts.show')Контроллер подключается через функцию с динамическим import(). Так файл загружается только при первом запросе к маршруту, а сервер стартует быстрее. Откройте /posts — появится «Список статей», а /posts/3 покажет «Статья номер 3».
Ресурсный контроллер
Флаг --resource создаёт контроллер сразу с семью методами: index, create, store, show, edit, update, destroy.
node ace make:controller comments --resourceК маршрутам его подключает одна строка router.resource('comments', CommentsController) — таблица адресов была в прошлом уроке. Если нужны не все методы, оставьте часть:
// start/routes.ts
router.resource('posts', PostsController).only(['index', 'show', 'create', 'store'])Метод except делает обратное — убирает перечисленные действия.
Отдельные методы и одиночные действия
Контроллер не обязан содержать все семь методов. Если у контроллера одно действие, назовите метод handle и подключайте класс без имени метода:
// start/routes.ts
const HomeController = () => import('#controllers/home_controller')
router.get('/', [HomeController])Роутер сам вызовет handle.
Частая ошибка
Импорт контроллера обычной строкой import PostsController from '#controllers/posts_controller' тоже работает, но редактор и документация AdonisJS советуют ленивый импорт. С обычным импортом при каждом запуске загружаются все контроллеры вместе с их зависимостями, и ошибка в одном файле ломает весь сервер. Пишите const PostsController = () => import('#controllers/posts_controller').