Гайд по Nest.js: что это такое и как написать свой первый код

Nest.js — самый важный и популярный фреймворк для создания серверных веб-приложений Node.js. В этом большом гайде мы поможем новичкам сделать первый шаг в освоении этого фреймворка для серверного JavaScript и расскажем, в чем вообще особенности Nest.js.
Для комфортного усвоения этого гайда вам потребуется:
- Знание JavaScript на среднем уровне
- Знание основ TypeScript, особенно синтаксиса декораторов
- Базовые знания Node.js. Желательно, опыт с Express.js
- Знание базовых понятий MVC (Model-View-Controller)
Также нам понадобятся установленные на компьютер:
- Node.js версии 10+. Инструкция по установке
- Docker
Docker мы будем использовать для развертывания базы данных. Развертывание СУБД в контейнере — один из самых простых способов. Но если вы хотите использовать другой способ, или же работать с уже имеющейся СУБД — нет проблем. В таком случае Docker вам не понадобится.
Содержание
- Введение
- Создадим проект
- Точка входа
- Статьи
- Добавляем HTML-шаблоны
- Добавляем просмотр статей
- Добавляем статью
- Заключение
Введение
Зачем нам нужен фреймворк?
Большинство задач в программировании — типовые. Если не брать каких-то специфических бизнес-кейсов, скорее всего все возможные задачи уже решены другими программистами и не по одному разу. Не зря в среде программистов среде так часто можно услышать шутки о «велосипедостроении». Фреймворки помогают нам писать меньше шаблонного кода и сосредоточиться на том, какую полезную работу должна делать наша программа.
Первым супер-популярным веб-фреймворком для Node.js был express.js. Nest.js значительно расширяет его функциональность, добавляет декларативности, а также помогает разработчику строить приложение в соответствии с лучшими архитектурными практиками.
Для примера мы напишем небольшой блог, в котором можно просматривать и добавлять статьи. Конечно, это будет очень простое приложение, но его будет достаточно для первого знакомства.
Создадим проект
Чтобы каждый раз не приходилось настраивать проект с нуля, разработчики Nest.js вооружили нас консольной утилитой — @nestjs/cli
. Установим ее глобально:
Теперь в вашей директории с проектами выполним команду nest new
, указав имя проекта.
Когда cli закончит свою работу, мы можем перейти в директорию nestjs-getting-started и посмотреть, что получилось:
Все основные зависимости уже установлены, сборка TypeScript настроена. Кроме этого, создана папка src, которая и будет интересовать нас больше всего. Здесь уже есть несколько файлов — это демонстрационное приложение от создателей Nest.js.
Самое приятное, что приложение уже рабочее и его можно запустить. Делается это при помощи команды
Теперь, если ввести в адресную строку браузера http://localhost:3000
, то мы увидим возвращённую сервером фразу Hello world!.
Запущенное командой npm run start:dev
приложение будет перезагружаться каждый раз, когда изменяется исходный код проекта.
Остановить работающее приложение можно комбинацией клавиш Ctrl+C
.
Точка входа
Точкой входа в приложение на Nest.js, как и в любом другом MVC-подобном фреймворке, являются контроллеры. Пока в приложении имеется один: app.controller.ts:
Обратите внимание, что класс AppController
и метод getHello()
помечены декораторами @Controller()
и @Get()
. Nest.js очень широко использует декораторы, поэтому к ним лучше сразу привыкать. Они позволяют писать приложение в более декларативном ключе, указывая что мы хотим сделать, и оставляя детали реализации фреймворку.
Если читатель «плавает» в теме декораторов, рекомендуем к прочтению эту статью.
Декоратор @Get()
говорит, что когда в приложение придёт HTTP-запрос методом GET
на роут '/' (это значение по умолчанию, поэтому его можно не указывать), его следует направить в метод getHello()
.
Соответственно, значение, которое вернётся из метода, будет отправлено в теле ответа. Код ответа по умолчанию для GET-запросов — 200.
Метод getHello()
и конструктор мы пока удалим. Взамен создадим метод index()
, который будет возвращать статьи. Контроллер приобретёт такой вид:
Теперь, зайдя на http://localhost
мы вместо Hello world увидим такой JSON:Обратите внимание, что мы возвращаем не «голый» массив, а заворачиваем его в объект c ключом articles
. Нам это пригодится чуть дальше.
Статьи
Пришло время наполнить блог статьями. Но что такое «статья»? Каждая статья — объект, который будет иметь уникальный идентификатор, заголовок и контент.
Создадим в папке src новый файл article.model.ts и в нём опишем класс статьи:
Почему id — необязательный параметр, выяснится позже — когда будем подключать базу данных.
Теперь представим, что у нас в блоге уже есть парочка статей. Создадим файл articles.ts:
Осталось вернуть массив статей из метода index()
в контроллере:
Если теперь запустить приложение, мы увидим в браузере следующее:
Добавляем HTML-шаблоны
Для того, чтобы пользователю было комфортнее работать с сайтом, сервер должен вернуть браузеру ответ не в формате json, а в виде html-страницы.
Создадим в корне проекта директорию views — в ней мы будем размещать HTML-шаблоны.
Устанавливаем шаблонизатор
Nest.js по умолчанию не устанавливает никаких движков шаблонизации, так как не знает, какой именно по душе пользователю. Мы для этого примера возьмём pug (ранее известный как jade). Этот пакет нам придется установить самостоятельно:
Чтобы подключить pug, перепишем функцию bootstrap (main.ts
):
Первый шаблон
Наш первый шаблон index.pug будет выглядеть так:
Добавление стилей выходит за рамки этой статьи, поэтому оставим это на усмотрение читателя.
В контроллере добавим к методу index
декоратор @Render()
(импортируется из пакета @nestjs/common
):
@Render('index')
указывает фреймворку, что те данные, которые возвращаются из метода нужно не просто вернуть браузеру, а использовать для отрисовки шаблона с названием index (расширение не важно).
Готово. Теперь при запуске приложения мы увидим то, что и ожидали — html-страницу с двумя статьями.
Читайте также:
Что такое webpack externals и как их настроить.
Добавляем просмотр статей
В app.controller.ts добавим в импорт декоратор @Param()
и создадим новый метод:
Строка :id
в декораторе @Get()
означает, что в этот метод будут направлены запросы на корневой роут с параметром, например: GET http://localhost/1.
При помощи декоратора @Param()
мы можем достать этот идентификатор из URL, преобразовать его к числу (ParseIntPipe) и использовать для поиска нужной статьи.
Кроме декоратора @Param()
в Nest.js есть также декораторы @Query()
для query-параметров и @Body()
для тела запроса.
Добавим в папку views шаблон article.pug:
Шапка будет та же самая, только в тэге title
мы выведем название статьи. В теле страницы — ожидаемо title
и content
, а также ссылка «назад» — на главную страницу.
Осталось починить ссылки на главной странице:
Теперь, зайдя на главную страницу, можно кликнуть по ссылке «Читать» у любой из статей и увидеть содержимое статьи. А при клике на «Назад» — вернуться к списку статей. Также можно зайти на страницу по прямой ссылке, например http://localhost
/1.Добавляем статью
Чтобы создать новую статью, браузер должен отправить на сервер title
и content
POST-запросом. Чтобы реализовать это, добавим в контроллер перед методом article
два новых метода:
Метод getForm()
не требует никакого возвращаемого значения — он просто возвращает статический HTML.
В методе create()
реализуем добавление статьи в коллекцию. Думаю, читатель уже догадался, что декоратор @Post()
означает одноимённый HTTP-глагол. Декоратор @Body()
указывает фреймворку, что данные для параметра нужно брать из тела запроса. И, наконец, декоратор @Redirect(‘/’, 301)
говорит, что после добавления статьи требуется переадресовать пользователя. Первый аргумент - ‘/’ обозначает корневой роут (то есть, главную страницу), а 301 — код ответа.
Шаблон create-article.pug будет выглядеть так:
Добавление статей реализовано. На страницу добавления можно попасть, введя в адресной строке http://localhost
/create. Чтобы было чуть удобнее, добавим ссылку на эту страничку вниз списка статей. index.pug приобретёт такой вид:Заключение
Nest.js позволяет нам написать простое приложение с минимальными усилиями. Однако истинная мощь фреймворка станет очевидна при более глубоком погружении. Среди особенно мощных возможностей, выделяющих его на фоне других:
- Декларативное программирование при помощи декораторов
- Встроенный DI-контейнер (кратко о DI и IoC)
- Мощные специализированные middleware: интерцепторы, пайпы, гарды
- Механизм обработки ошибок «из коробки»
- Поддержка любых протоколов, помимо HTTP. На Nest.js можно писать сервисы на основе RabbitMQ, Nats, Kafka или даже просто TCP-протокола.
Чтобы освоить все это, а также более продвинутые возможности Nest.js, читателю предстоит пройти немалый путь, и автор надеется, что эта статья станет уверенным первым шагом на нем.
Весь код учебного проекта, который мы использовали в этой статье в качестве примера, вы можете посмотреть здесь.
Eonae
4 года назад