В этой статье я покажу вам шаг за шагом, как создать веб-API RESTful с помощью Node.js и Express.js, создав простой и полезный API Todo.

В этой статье предполагается, что у вас есть базовые знания JavaScript и возможности использования терминала.

Вы также можете создать веб-API в Node.js, используя другой фреймворк, кроме Express.js, но Express.js является одним из самых популярных веб-фреймворков для Node.js.

Я также опубликовал и задокументировал этот веб-API на сайте heroku. Вы можете изучить его, перейдя по этой ссылке;
https://todowebapi.herokuapp.com

Вы можете найти исходный код этого веб-API в этом репозитории github.

Перед стартом

Если вы никогда не использовали Node.js или менеджер пакетов npm, вам следует установить их.

Чтобы проверить, установлен ли уже на вашем компьютере Node.js, откройте терминал и выполните команду node -v. Если вы видите свою версию Node.js, она установлена. В противном случае перейдите по ссылке ниже.

Щелкните здесь, чтобы загрузить и установить Node.js (вы можете выбрать версию LTS)

И если у вас нет IDE или текстового редактора для написания javascript, я советую вам Visual Studio Code.

Щелкните здесь, чтобы загрузить VS Code (необязательно)

О экспресс-генераторе

Фактически, мы могли бы использовать express-generator инструмент, предназначенный для быстрого создания Express Web API, но я хочу создать этот API с нуля, потому что этот инструмент помещает некоторые дополнительные файлы и структуры папок, которые нам сейчас не нужны. Но вы можете использовать этот полезный инструмент в следующий раз при создании нового веб-API. Я не буду использовать его сейчас, чтобы не усложнять статью.

Создание проекта

Перейдите в корневую папку рабочего пространства и создайте там новую папку с именем "todo-api".

Затем создайте файлы "package.json" и "server.js" в папке "todo-api", как показано ниже.

package.json

{
    "name": "todo-api",
    "version": "1.0.0",
    "scripts": {
        "start": "node server.js"
    },
    "dependencies": {
        "express": "^4.16.4"
    }
}

server.js

const http = require('http');
const express = require('express');
const app = express();
app.use(express.json());
app.use('/', function(req, res) {
    res.send('todo api works');
});
const server = http.createServer(app);
const port = 5000;
server.listen(port);
console.debug('Server listening on port ' + port);

После создания вышеуказанных файлов откройте ваш терминал в папке "todo-api" и запустите npm installcommand.

Эта команда установит зависимости вашего проекта, которые указывают на файл "package.json".

После завершения процесса загрузки пакета загруженные файлы зависимостей будут установлены в папку "node_modules" в корне папки "todo-api".

После завершения установки пакета запустите npm start, чтобы запустить наш веб-API.

Теперь наш веб-API слушает. Чтобы увидеть результат, откройте свой веб-браузер, введите localhost:5000 в адресную строку и нажмите клавишу ВВОД.

В результате вы увидите ответ нашего обработчика запросов в своем браузере: «todo api works».

Это мертвенно-простой веб-API Express.js. И это требует некоторого развития. Например, нам нужна конечная точка api для получения элементов списка дел. Итак, давайте добавим для этого новую конечную точку API.

Создайте новую папку с именем "routes" в корне папки "todo-api".

Затем создайте файл "items.js" внутри папки "routes" и поместите в него следующие коды.

Окончательная структура папок должна быть такой, как показано ниже.

/todo-api
|-- node_modules
|-- routes
    `-- items.js
|-- package.json
`-- server.js

items.js

const express = require('express');
const router = express.Router();
const data = [
    {id: 1, title: 'Finalize project', order: 1, completed: false, createdOn: new Date()},
    {id: 2, title: 'Book ticket to London', order: 2, completed: false, createdOn: new Date()},
    {id: 3, title: 'Finish last article', order: 3, completed: false, createdOn: new Date()},
    {id: 4, title: 'Get a new t-shirt', order: 4, completed: false, createdOn: new Date()},
    {id: 5, title: 'Create dinner reservation', order: 5, completed: false, createdOn: new Date()},
];
router.get('/', function (req, res) {
    res.status(200).json(data);
});
router.get('/:id', function (req, res) {
    let found = data.find(function (item) {
        return item.id === parseInt(req.params.id);
    });
    if (found) {
        res.status(200).json(found);
    } else {
        res.sendStatus(404);
    }
});
module.exports = router;

Исходный код файла "items.js" содержит две конечные точки. Первый получает все задачи, а второй - один элемент, соответствующий заданному параметру id.

Перед тем, как тестировать маршруты элементов, мы должны зарегистрировать его в файле "server.js".

Измените файл "server.js", как показано ниже, чтобы зарегистрировать новые маршруты элементов.

server.js

const http = require('http');
const express = require('express');
const itemsRouter = require('./routes/items');
const app = express();
app.use(express.json());
app.use('/items', itemsRouter);
app.use('/', function(req, res) {
    res.send('todo api works');
});
const server = http.createServer(app);
const port = 5000;
server.listen(port);
console.debug('Server listening on port ' + port);

Теперь запустите npm start, чтобы запустить наш веб-API.

Затем откройте свой веб-браузер и введите localhost:5000/items в адресную строку и нажмите клавишу ВВОД.

В теле ответа вы увидите массив json todo items.

И напишите localhost:5000/items/3 в адресную строку и нажмите Enter.

В теле ответа вы увидите задачу с идентификатором 3.

Но еще не закончил.

CRUD-операции и HTTP-методы

Я думаю, нам потребуются операции CRUD для создания, чтения, обновления и удаления элементов списка дел.

У нас уже есть две конечные точки для получения предметов. Итак, нам нужны конечные точки Create, Update и Delete.

Давайте также добавим эти конечные точки в файл items.js.

Наш последний "items.js" файл и конечные точки должны быть такими, как показано ниже.

Краткое объяснение

Я хочу вкратце объяснить некоторые моменты из наших последних кодов.

Прежде всего, вы, должно быть, заметили, что наш api работает со статическими данными и хранит их в памяти. Все наши HTTP-методы GET, POST, PUT и DELETE просто управляют массивом json. Это делается с целью упростить статью и привлечь внимание к структуре веб-API.

Из-за этой ситуации наш метод POST имеет некоторую дополнительную логику, такую ​​как вычисление идентификаторов следующих элементов и номеров заказов.

Таким образом, вы можете изменить логику и структуры данных в этих http-методах, чтобы использовать базу данных или что угодно.

Тестирование API с помощью Postman

Мы протестировали методы GET нашего веб-API в нашем веб-браузере и увидели ответы. Но мы не можем напрямую протестировать HTTP-методы POST, PUT и DELETE в веб-браузере.

Если вы хотите протестировать и другие методы http, воспользуйтесь Почтальоном или другой http-утилитой.

Теперь я покажу вам, как протестировать веб-API с помощью Postman.

Прежде чем мы начнем, щелкните здесь и установите Postman.

При первом запуске Postman после установки вы увидите стартовое окно. Закройте это стартовое окно, нажав кнопку закрытия в правом верхнем углу. Затем вы должны увидеть следующий экран.

Отправка запроса GET

Перед отправкой запроса к API мы должны запустить его, выполнив команду npm start, как мы это делали раньше.

После запуска веб-API и отображения сообщения «Сервер прослушивает…» введите localhost:5000/items в адресную строку, как показано ниже, и нажмите кнопку «Отправить». Вы увидите массив элементов списка дел в качестве ответа API, как показано ниже.

Вы можете попробовать сделать то же самое, указав идентификатор элемента в URL-адресе запроса, например localhost:5000/items/3

Отправка запроса POST

Чтобы отправить запрос POST и создать новый элемент задачи, введите localhost:5000/items в адресную строку и измените команду HTTP на POST, щелкнув стрелку перед адресной строкой, как показано ниже.

Перед отправкой запроса POST вы должны добавить данные запроса в тело запроса, щелкнув вкладку тела и выбрав raw и JSON, как показано ниже.

Теперь нажмите кнопку «Отправить», чтобы отправить запрос POST в веб-API. Затем вы должны получить HTTP-код ответа «201 Created» и увидеть созданный элемент в теле ответа.

Чтобы увидеть последний статус задач, отправьте запрос на получение на адрес localhost:5000/items. Вы должны увидеть вновь созданный элемент в конце списка.

Отправка запроса PUT

Отправка запроса PUT очень похожа на отправку запроса POST.

Наиболее очевидное различие заключается в том, что URL-адрес запроса должен указывать на конкретный элемент, например, этот localhost:5000/items/3

И вы должны выбрать PUT в качестве http-глагола вместо POST и отправить все необходимые данные в теле запроса, в отличие от POST.

Например, вы можете отправить тело JSON в запросе PUT, как показано ниже.

Пример тела JSON для запроса PUT

{
    "title": "New title of todo item",
    "order": 3,
    "completed": false
}

Когда вы нажимаете кнопку «Отправить», вы должны получить HTTP-код ответа «204 No Content». Вы можете проверить обновленный элемент, отправив запрос на получение.

Отправка запроса на удаление

Чтобы отправить запрос DELETE, измените URL-адрес запроса так, чтобы он обращался к определенному идентификатору элемента, например localhost:5000/items/3

И выберите УДАЛИТЬ как http-глагол и нажмите кнопку «Отправить».

Вы должны получить HTTP-код ответа «204 No Content» в результате операции DELETE.

Отправьте запрос на получение и посмотрите последний статус списка.

О запросе DELETE Http

Несколько слов о HTTP-запросе DELETE. Вы, должно быть, заметили что-то в нашем коде удаления. Запрос DELETE возвращает «204 No Content» в каждой ситуации.

Запросы HTTP DELETE идемпотентны. Так что это значит? Если вы удаляете ресурс на сервере, отправляя запрос DELETE, он удаляется из коллекции. И каждый следующий запрос DELETE на том же ресурсе не изменит результат. Таким образом, вы не получите ответ «404 Not Found» во втором запросе. Каждый запрос возвращает один и тот же ответ независимо от того, успешно он или нет. Это означает идемпотентную операцию.

Заключение

Наконец, мы протестировали все http-методы нашего веб-API.

Как видите, все работает отлично.

Спасибо за ваше время и терпение.