Создаем наш первый API при помощи Node.js и Express: Разбираемся с REST API
() translation by (you can also view the original English article)
Разбираемся с REST и RESTful API
Если вы уже имели дело с современной веб-разработкой, то вам уже встречались термины вроде REST и API. Если вы слышали эти термины или работали с API, но еще не до конца поняли принцип их работы или как создать свой собственный API, то эта серия руководств для вас.
В этой серии мы начнем с обзора принципов и понятий REST. Затем мы приступим к созданию нашего собственного полностью работоспособного API, который работает на основе сервера, созданного при помощи Express и Node.js, и подключается к базе данных MySQL. После изучения руководств этой серии вы должны будете чувствовать себя уверенно при создании вашего собственного API или при работе с документацией уже существующего.
Предварительная подготовка
Для того чтобы получить от этого руководства максимум пользы, вы уже должны иметь базовые навыки работы с командной строкой, обладать базовыми знаниями по JavaScript и иметь на своем компьютере установленную глобально Node.js.
Что из себя представляют REST и RESTful API?
При помощи Representational State Transfer (* передача репрезентативного состояния), или REST, описывается архитектурный стиль для веб-сервисов. REST состоит из ряда стандартов или ограничивающих требований по обмену данными между различными системами, и для систем, которые работают согласно принципам REST, используется термин RESTful. REST – абстрактная концепция, это не язык, не фреймворк или тип программного обеспечения.
Для лучшего понимания REST вам могла бы помочь аналогия, когда сравнивается коллекция виниловых пластинок с сервисом для потоковой передачи аудио-данных (* способ воспроизведения аудио- и видеоматериалов из интернета без их предварительного скачивания в компьютер). В случае с виниловыми пластинками для их распространения необходимо, чтобы для каждой записи была создана полная копия. В случае же с сервисом для потоковой передачи аудио-данных та же самая музыка может распространяться неограниченный срок, если известны какие-либо данные, например название песни. В этом случае сервис для потоковой передачи аудио-данных является RESTful сервисом, а коллекция виниловых пластинок – нет.
API (Application Programming Interface) – интерфейс, который позволяет программам общаться друг с другом. RESTful API – просто API, который работает согласно принципам и понятиям REST. В случае с API, работающим в сети, сервер получает запрос при помощи конечной точки, где указан URL-адрес, и отправляет обратно ответ, которым часто являются данные в формате вроде JSON.
Принципы REST
К архитектуре REST выдвигаются шесть основных требований, перечисленных ниже:
- Унифицированный интерфейс: интерфейс компонентов должен быть одинаковым. Это достигается за счет использования стандарта URI для идентификации ресурсов – другими словами, путей, которые могли бы быть набраны в адресной строке браузера.
- Клиент-Сервер: сервер и клиент выполняют различные задачи: сервер хранит данные и выполняет с ними манипуляции, а клиент отправляет запросы и отображает ответы.
- Взаимодействия без запоминания состояния: вся информация о каждом запросе содержится в нем самом и не зависит от состояния сессии.
- Возможность использования кэш-памяти: клиент и сервер могут кэшировать ресурсы.
- Многоуровневая система: клиент может подключаться к конечному серверу или промежуточному слою вроде компенсатора (* инструмент для эффективного распределения приходящего к группе серверов траффика).
- Получение кода по запросу (Не обязательно): клиент может скачать код, за счет чего снижается его видимость в сети.
Запрос и ответ
Вы в курсе, что для всех веб-сайтов используется URL, который начинается с http
(или https
в случае использования безопасной версии протокола). HyperText Transfer Protocol, или HTTP, – метод коммуникации клиентов с серверами в Интернете.
Нам наиболее очевидно его существование, когда мы вводим в адресных строках наших браузеров URL-адреса, однако HTTP может использоваться не только для запрашивания веб-сайтов с серверов. Когда вы переходите по адресу URL, то, собственно, выполняете запрос по методу GET
для получения определенного ресурса, и веб-сайт, который вы видите, является телом ответа. Мы скоро рассмотрим запросы, выполняющиеся по методу GET
и другим.
HTTP работает путем открытия соединения TCP (Transmission Control Protocol – протокол управления передачей) к порту сервера (80
для http
, 443
для https
) для выполнения запроса, а прослушивающий запросы сервер отправляет ответы, в которых содержатся код ответа и тело.
Ответ должен состоять из URL, метода, информации заголовка и тела.
Методы запроса
Имеется четыре главных метода HTTP, известных также как глаголы HTTP, которые часто используются для взаимодействия с API в сети. За счет этих методов определяется действие, которое будет выполнено над любым данным ресурсом.
Методы запроса HTTP приблизительно соответствуют парадигме CRUD, что расшифровывается как Create, Update, Read, Delete (* создать, прочесть, обновить, удалить). Хотя CRUD относится к функциям, используемым при выполнении операций над базой данных, мы можем применить те основы конструирования к глаголам HTTP в RESTful API.
Действие | Метод запроса | Определение |
---|---|---|
Прочитать | GET | При помощи него выполняется получение ресурса |
Создать | POST | При помощи него выполняется создание нового ресурса |
Обновить | PUT | При помощи него выполняется обновление существующего ресурса |
Удалить | DELETE | При помощи него выполняется удаление ресурса |
GET
– безопасная операция, которая используется только для считывания данных и при выполнении которой состояние сервера не изменится. Каждый раз, когда вы вводите в вашем браузере URL-адрес, например https://www.google.com
, вы отправляете запрос по методу GET
к серверам Google.
POST
используется для создания нового ресурса. Знакомым для вас примером использования POST
должна послужить регистрация пользователя на веб-сайте или веб-приложении. После отправления формы на сервер мог бы быть отправлен запрос по методу POST
с данными пользователя, где эта информация далее была бы добавлена в базу данных.
При помощи метода PUT
существующий ресурс обновляется, что могло бы быть использовано для редактирования настроек существующего пользователя. В отличие от POST
PUT
– идемпотентный метод. Это означает, что при повторном выполнении запроса будет получаться тот же самый результат. Например если бы вы отправили тот же самый запрос по методу POST
для создания нового пользователя в базе данных множество раз, то в результате был бы создан новый пользователь с теми же данными. Однако в результате выполнения того же запроса по методу PUT
для того же самого пользователя неизменно выходил бы одинаковый результат.
При помощи запроса по методу DELETE
, как должно быть понятно из его названия, будет просто удален существующий ресурс.
Коды ответа
Как только запрос поступит на сервер, тот отправит ответ HTTP, в котором будут содержаться метаданные об ответе (заголовки) и тело. Первая и наиболее важная часть ответа – код состояния, который указывает на то, был ли запрос выполнен успешно, была ли совершена ошибка при его обработке или же на то, что должно быть выполнено иное действие.
Наиболее известным кодом ответа для вас должен быть 404
, что означает Not Found
(* сообщает, что запрашиваемый ресурс не существует на сервере). 404
входит в состав класса 4xx
кодов состояния, при помощи которых указывается, что при обработке запроса произошла ошибка. Имеется пять классов кодов состояния, в каждом из которых имеется ряд кодов.
-
1xx
: Information (* Информация о процессе передачи) -
2xx
: Success (* Информация об успешном принятии и обработке запроса клиента)
-
3xx
: Redirection (* Перенаправление)
-
4xx
: Client Error (* Информация об ошибках со стороны клиента)
-
5xx
: Server Error (* Информация об ошибках со стороны сервера)
Другими распространенными кодами ответов, с которыми вы, скорее всего, знакомы, являются 301 Moved Permanently
, который используется для перенаправления браузера по другому URL-адресу, и 500 Internal Server Error
, что указывает на то, что при обработке запроса произошла непредвиденная ошибка на стороне сервера, из-за чего текущий запрос не может быть выполнен.
Что касается API RESTful и их соответственных глаголов HTTP, то коды всех ответов должны находиться в диапазоне 2xx
.
Запрос | Ответ |
---|---|
GET | 200 (OK) |
POST | 201 (Created) (* Создано) |
PUT | 200 (OK) |
DELETE | 200 (OK), 202 (Accepted) (* Принято) или 204 (No Content) (* Нет содержимого; тело сообщения не передается) |
200 OK
– код ответа, который указывает на то, что запрос был выполнен успешно. Он используется в качестве кода ответа при отправлении запроса по методу GET
или PUT
. При выполнении запросов по методу POST
будет возвращен ответ с кодом состояния 201 Created
для указания того, что новый ресурс был создан, и при выполнении запросов по методу DELETE
возможны несколько вариантов кодов ответа, благодаря которым подтверждается, что либо запрос был успешно принят (202
), либо отправлять нечего, поскольку ресурс более не существует (204
).
Мы можем протестировать код состояния ответа на запрос ресурса при помощи cURL – инструмента командной строки, который используется для передачи данных при помощи URL-адресов. При помощи команды curl
, за которой следует флажок -i
или --include
будет отправлен запрос по методу GET
по указанному URL-адресу и отображены заголовки и тело. Мы можем протестировать это, если откроем консоль и отправим запросы к Google.
1 |
curl -i https://www.google.com |
Сервера Google пришлют ответ со следующей информацией:
1 |
HTTP/2 200 |
2 |
date: Tue, 14 Aug 2018 05:15:40 GMT |
3 |
expires: -1 |
4 |
cache-control: private, max-age=0 |
5 |
content-type: text/html; charset=ISO-8859-1 |
6 |
... |
Как видно, в ответ на запрос curl
было отправлено множество заголовков и все тело HTML-ответа. Поскольку запрос был выполнен успешно, то первой частью ответа является код состояния 200
вместе с версией HTTP (ею может быть либо HTTP/1.1, либо HTTP/2).
Поскольку в ответ на этот конкретный запрос в ответе приходит веб-сайт, то в качестве значения заголовка content-type
(тип MIME (* Multipurpose Internet Mail Extensions – многоцелевые расширения почты (почтовой службы)) указывается text/html
. В RESTful API вы, скорее всего, увидите вместо этого application/json
, что указывает на то, что форматом ответа является JSON.
Интересно то, что мы можем увидеть иной тип ответа, слегка изменив вводимый URL-адрес. Выполните команду curl
для отправления запроса к Google без www
.
1 |
curl -i https://google.com |
1 |
HTTP/2 301 |
2 |
location: https://www.google.com/ |
3 |
content-type: text/html; |
4 |
charset=UTF-8 |
Google перенаправит клиент на www.google.com
, и в ответе будет прислан код состояния 301
для указания того, что должно быть выполнено перенаправление.
Конечные точки RESTful API
Когда API располагается на сервере, то предоставляемые им данные доступны при помощи конечных точек. Конечная точка – отдельная функция API, которая запускается при обращении к серверу по определенному URL-адресу и может принимать и обрабатывать запросы по методу GET
, POST
, PUT
или DELETE
.
URL API будет состоять из корня, пути и необязательной строки запроса.
- Корень, например
https://api.example.com
илиhttps://api.example.com/v2
, – корень URL, который может состоять из протокола, домена и версии протокола. - Путь, например
/users/
или/users/5
, – уникальное местоположение определенного ресурса. - Параметры запроса (указывать необязательно), например
?location=chicago&age=29
, – необязательные пары ключ=значение, которые используются для сортировки, фильтрации и разбиения контента на страницы.
Мы можем собрать эти компоненты воедино для получения нечто подобного тому, что показано в примере ниже, благодаря чему был бы возвращен список всех пользователей и использован параметр запросаlimit
для того, чтобы в результате фильтрации в ответ были включены только 10 результатов.
https://api.example.com/users?limit=10
Обычно, когда люди ссылаются на API как на RESTful API, они имеют ввиду соглашения о названиях, которые используются для построения URL конечной точки API. Несколько важных соглашений для стандартного RESTful API представлены ниже:
- Названия путей должны быть указаны во множественном числе: например для того чтобы получить данные о пользователе с id
5
, мы бы воспользовались/users/5
, а не/user/5
. - В URL не должно содержаться расширения файла: несмотря на то что при обращении к конечной точке API, скорее всего, будет возвращаться файл в формате JSON, URL не должен оканчиваться на
.json
. - В URL должны использоваться существительные, а не глаголы: слова вроде
add
иdelete
не должны содержаться в URL, используемом в RESTful API. Для добавления нового пользователя вы могли бы просто отправитьPOST
-запрос по адресу, в котором используется/users
, а не что-то вроде/users/add
. API должен разрабатываться так, чтобы был способен обрабатывать различные типы запросов по тому же самому URL-адресу. - Пути чувствительны к регистру (заглавным или строчным буквам) и должны быть написаны в нижнем регистре с использованием дефисов, а не символов подчеркивания.
Все эти соглашения являются рекомендациями, поскольку нет строгих стандартов REST, которых необходимо придерживаться. Однако если будете придерживаться их, то ваш API будет единообразным по стилю, узнаваемым для других разработчиков и легким для прочтения и понимания.
Заключение
В этом руководстве мы рассмотрели, что из себя представляют REST и RESTful API, как работают методы запроса HTTP и коды ответа, структуру URL API и основные соглашения RESTful API. В следующем руководстве мы рассмотрим, как применять всю эту теорию на практике на примере создания сервера при помощи Express и Node.js и создания нашего собственного API.