Статьи

Создайте свой первый API с помощью Node.js и Express: подключите базу данных

В первом руководстве « Понимание API-интерфейсов RESTful» мы узнали, что такое архитектура REST, каковы методы и ответы HTTP-запросов и как понять конечную точку API-интерфейса RESTful. Во втором учебном пособии « Как настроить сервер Express API» мы узнали, как создавать серверы со встроенным http модулем Node и платформой Express, а также как маршрутизировать созданное нами приложение на разные конечные точки URL.

В настоящее время мы используем статические данные для отображения информации о пользователях в виде фида JSON, когда конечная точка API получает запрос GET . В этом руководстве мы собираемся настроить базу данных MySQL для хранения всех данных, подключиться к базе данных из нашего приложения Node.js и позволить API использовать методы GET , POST , PUT и DELETE для создания полный API.

До этого момента мы не использовали базу данных для хранения или манипулирования какими-либо данными, поэтому собираемся ее создать. В этом руководстве будет использоваться MySQL, и, если на вашем компьютере уже установлен MySQL, вы будете готовы перейти к следующему шагу.

Если у вас не установлен MySQL, вы можете скачать MAMP для macOS и Windows, который предоставляет бесплатную локальную серверную среду и базу данных. После того, как вы это загрузили, откройте программу и нажмите Start Servers, чтобы запустить MySQL.

В дополнение к настройке самого MySQL мы хотим, чтобы программное обеспечение с графическим интерфейсом для просмотра базы данных и таблиц. Для Mac загрузите SequelPro , а для Windows загрузите SQLyog . После загрузки и запуска MySQL вы можете использовать SequelPro или SQLyog для подключения к localhost с именем пользователя root и паролем root на порту 3306 .

После того, как все настроено здесь, мы можем перейти к настройке базы данных для нашего API.

В программном обеспечении для просмотра базы данных добавьте новую базу данных и назовите ее api . Убедитесь, что MySQL работает, иначе вы не сможете подключиться к localhost .

После создания базы данных api перейдите в нее и выполните следующий запрос, чтобы создать новую таблицу.

1
2
3
4
5
6
CREATE TABLE `users` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(30) DEFAULT »,
  `email` varchar(50) DEFAULT »,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Этот SQL-запрос создаст структуру таблицы наших users . У каждого пользователя будет автоматически увеличивающийся идентификатор, имя и адрес электронной почты.

Мы также можем заполнить базу данных теми же данными, которые мы в настоящее время отображаем через статический массив JSON, выполнив запрос INSERT .

1
2
3
INSERT INTO users (name, email)
    VALUES (‘Richard Hendricks’, ‘[email protected]’),
           (‘Bertram Gilfoyle’, ‘[email protected]’);

Нет необходимости вводить поле id , так как оно автоматически увеличивается. На данный момент у нас есть структура нашей таблицы, а также некоторые примеры данных для работы.

Вернувшись в наше приложение, мы должны подключиться к MySQL из Node.js, чтобы начать работу с данными. Ранее мы установили модуль mysql npm и теперь собираемся его использовать.

Создайте новый каталог с именем data и создайте файл config.js .

Мы начнем с требования модуля mysql в data / config.js .

1
const mysql = require(‘mysql’);

Давайте создадим объект config который содержит хост, пользователя, пароль и базу данных. Это должно относиться к базе данных api мы создали, и использовать настройки по умолчанию localhost.

1
2
3
4
5
6
7
// Set database connection credentials
const config = {
    host: ‘localhost’,
    user: ‘root’,
    password: ‘root’,
    database: ‘api’,
};

Для эффективности мы собираемся создать пул MySQL , который позволит нам использовать несколько соединений одновременно, вместо того, чтобы вручную открывать и закрывать несколько соединений.

1
2
// Create a MySQL pool
const pool = mysql.createPool(config);

Наконец, мы экспортируем пул MySQL, чтобы приложение могло его использовать.

1
2
// Export the pool
module.exports = pool;

Вы можете увидеть завершенный файл конфигурации базы данных в нашем репозитории GitHub.

Теперь, когда мы подключаемся к MySQL и наши настройки завершены, мы можем перейти к взаимодействию с базой данных из API.

В настоящее время наш файл routes.js вручную создает массив пользователей JSON, который выглядит следующим образом.

Поскольку мы больше не будем использовать статические данные, мы можем удалить весь этот массив и заменить его ссылкой на наш пул MySQL.

1
2
// Load the MySQL pool connection
const pool = require(‘../data/config’);

Ранее GET для пути /users отправлял данные статических users . Наш обновленный код будет запрашивать базу данных для этих данных. Мы собираемся использовать запрос SQL, чтобы SELECT все из таблицы users , которая выглядит следующим образом.

1
SELECT * FROM users

Вот как будет выглядеть наш маршрут new /users get с использованием pool.query() .

1
2
3
4
5
6
7
8
// Display all users
app.get(‘/users’, (request, response) => {
    pool.query(‘SELECT * FROM users’, (error, result) => {
        if (error) throw error;
 
        response.send(result);
    });
});

Здесь мы выполняем запрос SELECT а затем отправляем результат в виде JSON клиенту через конечную точку /users . Если вы перезапустите сервер и перейдете на страницу /users , вы увидите те же данные, что и раньше, но теперь они динамические.

До сих пор нашими конечными точками были статические пути — либо / root, либо /users — но что делать, когда мы хотим видеть данные только о конкретном пользователе? Нам нужно будет использовать переменную конечную точку.

Для наших пользователей мы можем получить информацию о каждом отдельном пользователе на основе его уникального идентификатора. Для этого мы будем использовать двоеточие (:), чтобы обозначить, что это параметр маршрута.

1
2
3
4
5
// Display a single user by ID
app.get(‘/users/:id’, (request, response) => {
        …
    });
});

Мы можем получить параметр для этого пути с помощью свойства request.params . Поскольку наша именуется id , мы будем обращаться к ней.

1
const id = request.params.id;

Теперь мы добавим предложение WHERE в нашу SELECT чтобы получить только результаты с указанным id .

Мы будем использовать ? в качестве заполнителя, чтобы избежать внедрения SQL и передавать идентификатор в качестве параметра, вместо создания объединенной строки, которая была бы менее безопасной.

1
2
3
4
5
pool.query(‘SELECT * FROM users WHERE id = ?’, id, (error, result) => {
    if (error) throw error;
 
    response.send(result);
});

Полный код нашего отдельного пользовательского ресурса теперь выглядит так:

01
02
03
04
05
06
07
08
09
10
// Display a single user by ID
app.get(‘/users/:id’, (request, response) => {
    const id = request.params.id;
 
    pool.query(‘SELECT * FROM users WHERE id = ?’, id, (error, result) => {
        if (error) throw error;
 
        response.send(result);
    });
});

Теперь вы можете перезагрузить сервер и перейти по https://localhost/users/2 чтобы увидеть только информацию для Gilfoyle. Если вы получаете сообщение об ошибке, например Cannot GET /users/2 , это означает, что вам необходимо перезагрузить сервер.

Переход по этому URL должен вернуть один результат.

Если это то, что вы видите, поздравляю: вы успешно настроили динамический параметр маршрута!

Пока что все, что мы делали, использовало запросы GET . Эти запросы безопасны, то есть они не изменяют состояние сервера. Мы просто просматривали данные JSON.

Теперь мы собираемся сделать API действительно динамичным, используя запрос POST для добавления новых данных.

Ранее в статье «Понимание REST» я упоминал, что мы не используем глаголы типа « add или « delete в URL для выполнения действий. Чтобы добавить нового пользователя в базу данных, мы отправим POST по тому же URL-адресу, с которого мы его просматриваем, но просто настроим для него отдельный маршрут.

1
2
3
4
// Add a new user
app.post(‘/users’, (request, response) => {
    …
});

Обратите внимание, что теперь мы используем app.post() вместо app.get() .

Поскольку мы создаем вместо чтения, мы будем использовать запрос INSERT здесь, так же, как мы это делали при инициализации базы данных. Мы отправим весь request.body через SQL-запрос.

1
2
pool.query(‘INSERT INTO users SET ?’, request.body, (error, result) => {
   if (error) throw error;

Мы также собираемся указать статус ответа как 201 , что означает « Created . Чтобы получить идентификатор последнего вставленного элемента, мы будем использовать свойство insertId .

1
response.status(201).send(`User added with ID: ${result.insertId}`);

Весь наш код приема POST будет выглядеть следующим образом.

1
2
3
4
5
6
7
8
// Add a new user
app.post(‘/users’, (request, response) => {
    pool.query(‘INSERT INTO users SET ?’, request.body, (error, result) => {
        if (error) throw error;
 
        response.status(201).send(`User added with ID: ${result.insertId}`);
    });
});

Теперь мы можем отправить запрос POST через. Большую часть времени, когда вы отправляете запрос POST , вы делаете это через веб-форму. Мы узнаем, как это настроить, к концу этой статьи, но самый быстрый и простой способ отправить тестовый POST — это cURL с использованием флага -d (--data) .

Мы запустим curl -d , а затем строку запроса, содержащую все пары ключ / значение и конечную точку запроса.

1
curl -d «name=Dinesh Chugtai&[email protected]» http://localhost:3002/users

Как только вы отправите этот запрос, вы должны получить ответ от сервера.

Если вы перейдете по http://localhost/users , вы увидите последнюю запись, добавленную в список.

POST полезен для добавления нового пользователя, но мы хотим использовать PUT для изменения существующего пользователя. PUT является идемпотентом, то есть вы можете отправить один и тот же запрос несколько раз, и будет выполнено только одно действие. Это отличается от POST , потому что если мы отправим наш запрос нового пользователя более одного раза, он будет создавать новых пользователей.

Для нашего API мы собираемся настроить PUT чтобы иметь возможность обрабатывать редактирование одного пользователя, поэтому на этот раз мы будем использовать параметр маршрута :id .

Давайте создадим запрос UPDATE и убедимся, что он применяется только к запрошенному идентификатору с WHERE . Мы используем два ? заполнители, и значения, которые мы передаем, будут идти в последовательном порядке.

01
02
03
04
05
06
07
08
09
10
// Update an existing user
app.put(‘/users/:id’, (request, response) => {
    const id = request.params.id;
 
    pool.query(‘UPDATE users SET ? WHERE id = ?’, [request.body, id], (error, result) => {
        if (error) throw error;
 
        response.send(‘User updated successfully.’);
    });
});

Для нашего теста мы отредактируем пользователя 2 и обновим адрес электронной почты от [email protected] до [email protected] . Мы можем снова использовать cURL с флагом [-X (--request)] , чтобы явно указать, что мы отправляем запрос PUT.

1
curl -X PUT -d «name=Bertram Gilfoyle» -d «[email protected]» http://localhost:3002/users/2

Обязательно перезапустите сервер перед отправкой запроса, иначе вы получите ошибку Cannot PUT /users/2 .

Вы должны увидеть это:

Пользовательские данные с идентификатором 2 теперь должны быть обновлены.

Нашей последней задачей для завершения функциональности CRUD API является возможность удаления пользователя из базы данных. Этот запрос будет использовать SQL-запрос DELETE с WHERE и удалит отдельного пользователя, указанного параметром маршрута.

01
02
03
04
05
06
07
08
09
10
// Delete a user
app.delete(‘/users/:id’, (request, response) => {
    const id = request.params.id;
 
    pool.query(‘DELETE FROM users WHERE id = ?’, id, (error, result) => {
        if (error) throw error;
 
        response.send(‘User deleted.’);
    });
});

Мы можем снова использовать -X с cURL, чтобы отправить удаление через. Давайте удалим самого последнего пользователя, которого мы создали.

Вы увидите сообщение об успехе.

Перейдите по http://localhost:3002 , и вы увидите, что сейчас есть только два пользователя.

Поздравляем! На данный момент API завершен. Посетите репозиторий GitHub, чтобы увидеть полный код файла rout.js.

В начале этой статьи мы установили четыре зависимости, одной из которых был модуль request . Вместо использования запросов cURL, вы можете создать новый файл со всеми данными и отправить его через. Я создам файл с именем post.js , который создаст нового пользователя через POST .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
const request = require(‘request’);
 
const json = {
    «name»: «Dinesh Chugtai»,
    «email»: «[email protected]»,
};
 
request.post({
    url: ‘http://localhost:3002/users’,
    body: json,
    json: true,
}, function (error, response, body) {
    console.log(body);
});

Мы можем вызвать это с помощью node post.js в новом окне терминала во время работы сервера, и это будет иметь тот же эффект, что и использование cURL. Если что-то не работает с cURL, модуль request полезен, так как мы можем просмотреть ошибку, ответ и тело.

Обычно POST и другие методы HTTP, которые изменяют состояние сервера, отправляются с использованием форм HTML. В этом очень простом примере мы можем создать файл index.html в любом месте и создать поле для имени и адреса электронной почты. Действие формы будет указывать на ресурс, в данном случае http//localhost:3002/users , и мы будем указывать метод как post .

Создайте index.html и добавьте в него следующий код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html lang=»en»>
 
<head>
    <meta charset=»utf-8″>
    <meta name=»viewport» content=»width=device-width, initial-scale=1.0″>
 
    <title>Node.js Express REST API</title>
</head>
 
<body>
    <form action=»http://localhost:3002/users» method=»post»>
        <label for=»name»>Name</label>
        <input type=»text» name=»name»>
        <label for=»email»>Email</label>
        <input type=»email» name=»email»>
        <input type=»submit»>
    </form>
</body>
 
</html>

Откройте этот статический HTML-файл в вашем браузере, заполните его и отправьте, когда сервер работает в терминале. Вы должны увидеть ответ User added with ID: 4 , и вы сможете увидеть новый список пользователей.

В этом руководстве мы узнали, как подключить сервер Express к базе данных MySQL и настроить маршруты, соответствующие методам GET , POST , PUT и DELETE для путей и параметров динамического маршрута. Мы также узнали, как отправлять HTTP-запросы на сервер API с использованием cURL, модуля request Node.js и HTML-форм.

К этому моменту у вас должно быть очень хорошее понимание того, как работают API RESTful, и теперь вы можете создать свой собственный полноценный API в Node.js с Express и MySQL!