Недавно моему другу было поручено следующее:
Создайте простую регистрационную форму с полями имя, адрес электронной почты и пароль в предпочитаемой среде JavaScript (Angular, React, Vue…). Создайте сервер Express с одним маршрутом POST
/api/user/validate
, который будет проверять поля формы при отправке с помощью AJAX. Если все в порядке, верните200
и сообщение об успешном выполнении, в противном случае верните422
и список сообщений об ошибках.
Так как раньше он никогда не работал с Экспрессом, он попросил меня о помощи. Он будет делать фронтенд, я - бэкэнд. У меня тоже не было большого опыта работы с Express, но я хотел попробовать. Что меня шокировало, так это то, что такую простую задачу было довольно сложно выполнить, если вы не совсем понимали, что происходит.
Итак, в этом посте я расскажу, как мне удалось настроить Express для данного задания. Он полностью удобен для новичков и показывает, как быстро сформировать простой API на основе Node с помощью Express.
Экспресс-версия на момент написания этого сообщения была 4.16.4.
Установка
Сначала я создал новую папку и инициализировал новый проект Node (создан package.json
).
$ mkdir express-validator $ cd express-validator $ npm init -y
Далее я установил Express.
$ npm install express --save
После установки Express я создал server.js
файл, который собирался использовать в качестве основного файла сервера.
$ touch server.js
Создание экспресс-экземпляра
Пришло время добавить Express и создать его экземпляр в server.js
файле. Итак, в верхней части файла я добавил следующее:
const express = require('express'); const app = express();
Первая строка добавила в приложение модуль Express, а вторая создала его экземпляр.
Создание маршрута
Теперь у нас есть готовый экземпляр Express, но нет маршрутов для попадания. В задании говорилось, что нам нужен POST-маршрут /api/user/validate
. Давай создадим это.
const express = require('express'); const app = express(); app.post('/api/user/validate', (req, res) => { // Route handler code goes here. });
Насколько это было легко? Теперь, когда запрос POST достигает /api/user/validate
маршрута, наш обработчик маршрута срабатывает и отвечает. Если вам нужен метод GET, вы должны использовать app.get
. req
и res
- это объекты, которые содержат данные, связанные с запросом и ответом соответственно, и могут использоваться внутри обработчика маршрута для отправки и получения данных. Подробнее о них вы можете прочитать здесь. Давайте добавим код в обработчик маршрута.
const express = require('express'); const app = express(); app.post('/api/user/validate', (req, res) => { let success = false; const payload = {}; // Validation code goes here. if(success) { res.status(200); } else { res.status(422); } res.json(payload); }
Мы определили две переменные - success
и payload
. success
- это просто флаговая переменная для демонстрации сценария годен / не годен. payload
- это фактические данные, которые мы отправили бы в качестве ответа с помощью функции res.json
, которая (очевидно :) отправляет ответ JSON. Код состояния, который будет отправлен обратно, изменяется с помощью функции res.status
(опять же, очевидно :).
Обратите внимание, что переменные относятся только к моему примеру, они могут вам не понадобиться. :)
Запуск сервера
Наш маршрут готов. Пора запустить сервер и попытаться попасть в маршрут. Для запуска сервера воспользуемся функцией app.listen
.
const express = require('express'); const app = express(); const port = 3000; app.post('/api/user/validate', (req, res) => { let success = false; const payload = {}; // Validation code goes here. if(success) { res.status(200); } else { res.status(422); } res.json(payload); } app.listen(port, () => console.log(`Express validator is running on port ${port}.`));
Чтобы сделать его более гибким, я создал переменную port
, в которой хранится порт, который приложение будет прослушивать. Как только сервер будет запущен, он просто запишет данное сообщение в терминал.
Запустим сервер.
$ node server
Если все прошло хорошо, вы должны увидеть сообщение в своем терминале.
Express validator is running on port 3000.
Гм ... что случилось?
Сервер был запущен, и мой друг закончил с клиентской частью. Он использовал Axios для отправки AJAX-запроса на маршрут.
axios.post('https://localhost:3000/api/user/validate', { name, email, password }).then(response => { /* ... */ });
Когда запрос был (не) отправлен, мы знали, что на этом не закончили.
CORS
Первая проблема, с которой мы столкнулись, была CORS. Поскольку интерфейсное приложение и сервер не работали в одном домене (порте), мы не могли передавать данные между ними. Чтобы исправить это, я установил промежуточное ПО cors.
npm install cors --save
После того, как он был установлен, я добавил его на сервер.
const express = require('express'); const cors = require('cors'); const app = express(); const port = 3000; app.use(cors()); app.post('/api/user/validate', (req, res) => { let success = false; const payload = {}; // Validation code goes here. if(success) { res.status(200); } else { res.status(422); } res.json(payload); } app.listen(port, () => console.log(`Express validator is running on port ${port}.`));
Мы перезапустили сервер и снова попытались пройти по маршруту. Наконец, мы получили ответ от сервера.
Тело запроса
Хорошо, запрос прошел, и мы получили ответ. Однако данные, которые мы отправили с помощью Axios, не были распознаны. Я пытался регистрировать req.body
внутри обработчика маршрута, но всегда был {}
(пустой объект).
Сначала я подумал, что что-то не так с настройками Axios, и это способ отправки данных. Я был неправ. Route не знал, как обрабатывать данные (тело), когда он их получил. Нам не хватало парсера.
Чтобы исправить это, я установил body-parser. Это промежуточное программное обеспечение синтаксического анализа, которое анализирует тело запроса до того, как оно попадет в обработчик.
npm install body-parser --save
После того, как он был установлен, я добавил его на сервер.
const express = require('express'); const cors = require('cors'); const bodyParser = require('body-parser'); const app = express(); const port = 3000; app.use(cors()); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); app.post('/api/user/validate', (req, res) => { let success = false; const payload = {}; // Validation code goes here. if(success) { res.status(200); } else { res.status(422); } res.json(payload); } app.listen(port, () => console.log(`Express validator is running on port ${port}.`));
С установленным парсером тела наш сервер теперь понимает тела application/json
и application/x-www-form-urlencoded
.
Успех
Мы снова перезапустили сервер и пытаемся попасть в маршрут. Наконец-то! Наш сервер выполнил проверку и отправил ответ соответственно. Мы закончили!
Последние мысли
Это был всего лишь краткий обзор самого простого сервера Express, который может получать и анализировать данные JSON. Я рад, что ввязался в это дело, потому что столкнулся с проблемами, о которых никогда бы не подумал. Я обязательно продолжу читать и поэкспериментировать по этому поводу.