Недавно моему другу было поручено следующее:

Создайте простую регистрационную форму с полями имя, адрес электронной почты и пароль в предпочитаемой среде 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. Я рад, что ввязался в это дело, потому что столкнулся с проблемами, о которых никогда бы не подумал. Я обязательно продолжу читать и поэкспериментировать по этому поводу.