Что такое REST API?

Что такое REST API?

Что такое REST API? REST - это аббревиатура от Representational State Transfer - почти бессмысленное описание самой распространенной технологии веб-сервисов! REST API - это способ взаимодействия двух компьютерных систем с помощью технологий HTTP, используемых в веб-браузерах и серверах.

Обмен данными между двумя и более системами всегда был одним из основных требований при разработке программного обеспечения. Например, при покупке автостраховки. Страховщик должен получить информацию о Вас и Вашем автомобиле, поэтому он запрашивает данные у органов регистрации автомобилей, кредитных агентств, банков и других систем. Все это происходит прозрачно в режиме реального времени, чтобы определить, может ли страховщик предложить конкурентоспособный полис.

API (Application Programming Interfaces - интерфейсы прикладного программирования) способствуют такому взаимодействию между системами, предоставляя им интерфейс для общения друг с другом. REST - это просто широко распространенный стиль API, который мы используем для последовательного и предсказуемого взаимодействия с внутренними и внешними сторонами. Это можно сравнить с тем, как мы отправляем письмо с почтовой маркой, адресом и конвертом определенным образом, чтобы убедиться, что оно будет доставлено и прочитано.

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

Пример REST API

Это публичный API, реализованный как RESTful веб-сервис (он следует соглашениям REST). В браузере отображается один вопрос викторины в формате JSON с ответами, например:

{
	"response_code": 0,
	"results": [
		{
			"category": "Science: Computers",
			"type": "multiple",
			"difficulty": "easy",
			"question": "What does GHz stand for?",
			"correct_answer": "Gigahertz",
			"incorrect_answers": ["Gigahotz", "Gigahetz", "Gigahatz"]
		}
	]
}

Вы можете запросить тот же URL и получить ответ, используя любой HTTP-клиент, например curl:

curl "https://opentdb.com/api.php?amount=1&category=18"

Клиентские библиотеки HTTP доступны во всех популярных языках и средах исполнения, включая Fetch в JavaScript, Node.js и Deno и file_get_contents() в PHP. Ответ в формате JSON является машиночитаемым, поэтому его можно разобрать и использовать перед выводом в HTML или другие форматы.

REST API и остальное

В течение многих лет развивались различные стандарты передачи данных. Возможно, вам приходилось сталкиваться с такими вариантами, как CORBA, SOAP или XML-RPC. Большинство из них устанавливают строгие правила обмена сообщениями.

Вариант REST был определен в 2000 году Роем Филдингом и является значительно более простым, чем другие. Это не стандарт, а набор рекомендаций и ограничений для RESTful веб-сервисов. К ним относятся:

  • Клиент-сервер: СистемаА делает HTTP-запрос к URL-адресу, размещенному на сайте СистемыВ, которая возвращает ответ. Это идентично работе браузера. Браузер делает запрос на определенный URL. Запрос направляется на веб-сервер, который обычно возвращает HTML-страницу. Эта страница может содержать ссылки на изображения, таблицы стилей и JavaScript, что влечет за собой дополнительные запросы и ответы.

  • Другими словами, можно сделать два или более HTTP-запросов в любом порядке, и ответы будут одинаковыми (… если только API не рассчитан на случайные ответы, как в примере с викториной выше).

  • Кэшируемость: Ответ должен быть определен как кэшируемый или нет. Кэширование повышает производительность, поскольку нет необходимости заново генерировать ответ для одного и того же URL. Приватные данные, относящиеся к определенному пользователю в определенное время, обычно не кэшируются.

  • Уровневый: Запрашивающий клиент не должен знать, общается ли он с реальным сервером, прокси или любым другим посредником.

Создание RESTful Web-сервиса

RESTful веб-сервис запрос содержит:

  1. Адрес конечной точки. Приложение, реализующее RESTful API, определяет одну или несколько конечных точек URL с указанием домена, порта, пути и/или строки запроса - например, https://mydomain/user/123?format=json.

  2. Метод HTTP. В любой конечной точке могут использоваться различные HTTP-методы, которые соответствуют операциям создания, чтения, обновления и удаления (CRUD), выполняемым приложением:

HTTP-метод    CRUD  Action                        
GET          read  возвращает запрошенные данные
POST          createсоздание новой записи        
PUT или PATCHupdateобновляет существующую запись
DELETE        deleteудаляет существующую запись  

Примеры:

  • GET-запрос к /user/ возвращает список зарегистрированных пользователей в системе

  • POST-запрос к /user/ создает пользователя с идентификатором 123, используя данные тела (см. 4. ниже). В ответ возвращается идентификатор.

  • PUT-запрос к /user/123 обновляет пользователя 123, используя основные данные (см. 4. ниже)

  • GET-запрос к /user/123 возвращает данные о пользователе 123.

  • запрос DELETE к /user/123 удаляет пользователя 123.

  1. HTTP-заголовки. В заголовке HTTP-запроса может содержаться такая информация, как маркеры аутентификации или cookies.

  2. Тело данных. Данные обычно передаются в теле HTTP-запроса аналогично HTML-представлениям <form> или путем отправки одной строки данных в кодировке JSON.

Пример запроса REST API
Пример запроса REST API

REST API Response

Полезная нагрузка ответа может быть любой: данные, HTML, изображение, аудиофайл и т.д. Обычно ответы на данные кодируются в JSON, но можно использовать XML, CSV, простые строки или любой другой формат. Можно разрешить указывать формат ответа в запросе - например, /user/123?format=json или /user/123?format=xml.

В заголовке ответа также должен быть задан соответствующий HTTP status code. Для успешных запросов используется 200 OK, хотя при создании записи может быть возвращен и 201 Created. Ошибки должны возвращать соответствующий код, например, 400 Bad Request, 404 Not Found, 401 Unauthorized и т.д.

Могут быть установлены и другие HTTP-заголовки, включая директивы Cache-Control или Expires, определяющие, как долго ответ может кэшироваться, прежде чем он будет считаться устаревшим.

Однако строгих правил не существует. URL конечных точек, методы HTTP, тело данных и типы ответов могут быть реализованы как угодно. Например, POST, PUT и PATCH часто используются как взаимозаменяемые, так что любой из них будет создавать или обновлять запись по мере необходимости.

Пример REST API “Hello World”

Следующий код Node.js создает RESTful веб-сервис с использованием фреймворка Express. Единственная конечная точка /hello/ отвечает на HTTP GET-запросы.

Убедитесь, что у вас установлен Node.js, затем создайте новую папку с именем restapi. Создайте в этой папке новый файл package.json со следующим содержимым:

{
"name": "restapi",
"version": "1.0.0",
"description": "REST-тест",
"scripts": {
"start": "node ./index.js"
},
"dependencies": {
"express": "4.18.1"
}
}
 

Запустите npm install из командной строки для получения зависимостей, затем создайте файл index.js со следующим кодом:

// простой Express.js RESTful API
'use strict';
// инициализация
const port = 8888,
express = require('express'),
app = express();
 
// /hello/ GET-запрос
app.get('/hello/:name?', (req, res) =>
res.json(
{ message: `Hello ${req.params.name || 'world'}!` }
)
);
 
// запускаем сервер
app.listen(port, () =>
console.log(`Сервер запущен на порту ${порт}`);
);

Запустите приложение из командной строки с помощью npm start и откройте в браузере страницу http://localhost:8888/hello/. В ответ на GET-запрос отображается следующий JSON:

{
"message": "Hello world!"
}

API также позволяет задать пользовательское имя, поэтому http://localhost:8888/hello/everyone/ возвращает:

{
"message": "Всем привет!"
}
 

REST-запросы на стороне клиента и CORS

Рассмотрим следующую HTML-страницу, запущенную в браузере по URL http://localhost:8888/:

<!doctype html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<title>REST-тест</title>
	</head>
 
	<body>
		<script>
			fetch('http://localhost:8888/hello/')
				.then((response) => {
					return response.json();
				})
				.then((json) => {
					console.log(json);
				});
		</script>
	</body>
</html>

Вызов fetch выполняет тот же API-запрос, и в консоли браузера отображается Object { message: "Hello world!" }, как и следовало ожидать.

Однако предположим, что ваш RESTful веб-сервис теперь размещен в Интернете на домене http://mydomain.com/hello/. URL страницы JavaScript fetch() изменился соответствующим образом, но при открытии страницы http://localhost:8888/ в браузере теперь выдается консольная ошибка Cross-Origin Request Blocked.

В целях безопасности браузеры разрешают только клиентские вызовы XMLHttpRequest и Fetch API на тот же домен, где размещена вызывающая страница.

К счастью, Cross-origin Resource Sharing (CORS) позволяет обойти это ограничение безопасности. Установка заголовка HTTP-ответа Access-Control-Allow-Origin сообщает браузеру, что запрос разрешен. Он может быть задан для конкретного домена или * для всех доменов (реализовано с помощью API Quiz, описанного выше).

Код API веб-сервиса может быть изменен таким образом, чтобы разрешить доступ с любого клиентского скрипта, работающего на любом домене:

// /hello/ GET-запрос
 
app.get('/hello/:name?', (req, res) =>
	res
		.append('Access-Control-Allow-Origin', '*')
		.json({ message: `Hello ${req.params.name || 'world'}!` }),
);

В качестве альтернативы можно использовать промежуточную функцию Express.js, которая будет добавлять заголовок к каждому запросу конечной точки:

// включить CORS
 
app.use((req, res, next) => {
	res.append('Access-Control-Allow-Origin', '*');
 
	next();
});
 
// /hello/ GET-запрос

Обратите внимание, что браузеры делают два запроса к REST API:

  1. HTTP-запрос OPTIONS к тому же URL определяет, действителен ли заголовок HTTP-ответа Access-Control-Allow-Origin.

  2. Собственно REST-вызов

Когда ваш сервер получает метод запроса OPTIONS, он может установить заголовок HTTP-ответа Access-Control-Allow-Origin и вернуть фиктивный пустой ответ, чтобы исключить дублирование работы.

Вызовы REST API

Успех REST во многом объясняется его простотой. Разработчики могут реализовывать RESTful API по своему усмотрению, но это может привести к дополнительным проблемам. Для более детального рассмотрения стратегий реализации посмотрите нашу статью 13 лучших практик создания RESTful API.

Консенсус по конечным точкам

Рассмотрим следующие конечные точки:

  • /user/123

  • /user/id/123

  • /user/?id=123

Все они являются допустимыми вариантами получения данных для пользователя 123. При выполнении более сложных операций количество комбинаций увеличивается. Например, верните десять пользователей, чьи фамилии начинаются с ‘A’ и которые работают в компанииX, начиная с записи 51, если упорядочить их по дате рождения в обратном хронологическом порядке.

В конечном счете, не имеет значения, как форматировать URL-адреса, но важна согласованность во всем API. Это может оказаться сложной задачей для больших кодовых баз с большим количеством разработчиков.

Версионирование REST API

Изменения в API неизбежны, но URL конечных точек никогда не должны быть недействительными, иначе это приведет к поломке использующих их приложений.

Чтобы избежать проблем совместимости, API часто версифицируются. Например, /2.0/user/123 заменяет /user/123. При этом и новая, и старая конечная точка могут оставаться активными. К сожалению, в этом случае возникает необходимость поддерживать несколько исторических API. В конечном итоге старые версии могут быть отменены, но этот процесс требует тщательного планирования.

Аутентификация REST API

Приведенный выше API викторины является открытым: любая система может получить шутку без авторизации. Это не подходит для API, которые имеют доступ к частным данным или разрешают запросы на обновление и удаление.

Клиентские приложения, находящиеся в том же домене, что и RESTful API, будут отправлять и получать cookies так же, как и при любом другом HTTP-запросе. (Обратите внимание, что Fetch() в старых браузерах требует установки параметра credentials init option). Таким образом, запрос к API может быть проверен на предмет того, что пользователь вошел в систему и имеет соответствующие права.

Сторонние приложения должны использовать альтернативные методы авторизации. Общие опции аутентификации включают:

  • HTTP basic authentication. В заголовке запроса передается HTTP-заголовок Authorization, содержащий base64-кодированную строку имя пользователя:пароль.

  • API-ключи. Стороннее приложение получает разрешение на использование API путем выдачи ключа, который может иметь определенные права или быть ограниченным определенным доменом. Ключ передается в каждом запросе в HTTP-заголовке или в строке запроса.

  • OAuth. Токен получается перед выполнением любого запроса путем отправки идентификатора клиента и, возможно, секрета клиента на OAuth-сервер. Затем токен OAuth отправляется с каждым запросом к API до истечения срока его действия.

  • JSON Web Tokens (JWT). Токены аутентификации с цифровой подписью надежно передаются как в заголовке запроса, так и в заголовке ответа. JWT позволяют серверу кодировать права доступа, поэтому обращение к базе данных или другой системе авторизации не требуется.

Аутентификация API зависит от контекста использования:

  • В некоторых случаях стороннее приложение рассматривается как любой другой вошедший в систему пользователь с определенными правами и разрешениями. Например, картографический API может возвращать вызывающему приложению информацию о маршрутах между двумя точками. Он должен подтвердить, что приложение является действительным клиентом, но не должен проверять учетные данные пользователя.

  • В других случаях стороннее приложение запрашивает данные, закрытые для отдельного пользователя, например содержимое электронной почты. REST API должен идентифицировать пользователя и его права, но ему может быть безразлично, какое приложение вызывает API.

Безопасность REST API

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

Вопросы безопасности выходят за рамки данной статьи, но общие рекомендации включают:

  • использовать HTTPS

  • использовать надежный метод аутентификации

  • использовать CORS для ограничения обращений на стороне клиента к определенным доменам

  • обеспечивать минимальную функциональность - то есть не создавать опции DELETE, которые не требуются

  • проверять все URL-адреса конечных точек и данные тела

  • избегать раскрытия API-токенов в JavaScript на стороне клиента

  • блокировать доступ с неизвестных доменов или IP-адресов

  • блокировать неожиданно большие полезные нагрузки

  • учитывать ограничение скорости - т.е. количество запросов, использующих один и тот же API-токен или IP-адрес, не должно превышать N в минуту

  • отвечать соответствующим заголовком HTTP status code и caching

  • регистрировать запросы и расследовать отказы

Многочисленные запросы и ненужные данные

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

Рассмотрим RESTful API, предоставляющий доступ к данным об авторах и книгах. Чтобы показать данные о 10 самых продаваемых книгах, клиент может:

  • Запросить первые 10 книг /book/, упорядоченные по количеству продаж (первым идет самый продаваемый). Ответ содержит список книг с идентификатором каждого автора.

  • Выполнить до 10 запросов /author/{id} для получения данных о каждом авторе.

Это известно как проблема N+1; для каждого результата в родительском запросе необходимо выполнить N запросов API.

Если это распространенный вариант использования, то RESTful API можно изменить таким образом, чтобы каждая возвращаемая книга содержала полную информацию об авторе: его имя, возраст, страну, биографию и т.д. Можно даже предоставлять полную информацию о других книгах автора - хотя это может значительно увеличить полезную нагрузку на ответ!

Чтобы избежать неоправданно больших ответов, можно настроить API таким образом, чтобы сведения об авторе были необязательными - например, ?author_details=full. Количество опций, которые должны учитывать авторы API, может вызвать недоумение.

Исправляет ли GraphQL REST API?

Проблемы, связанные с REST, привели к тому, что компания Facebook создала GraphQL - язык запросов к веб-сервисам. Считайте, что это SQL для веб-сервисов: один запрос определяет, какие данные вам нужны и как вы хотите их получить.

GraphQL решает некоторые проблемы, возникающие при использовании RESTful API, но вводит и другие. Например, становится трудно кэшировать ответы на GraphQL.

Ваши клиенты вряд ли столкнутся с проблемами, сравнимыми с проблемами Facebook, поэтому, возможно, стоит рассмотреть возможность использования GraphQL после того, как RESTful API выйдет за свои практические рамки.

Ссылки на REST API и средства разработки

Существует множество инструментов для разработки RESTful API на всех языках. Среди них можно выделить следующие:

  • Swagger: разнообразные инструменты для разработки, документирования, моделирования, тестирования и мониторинга REST API.

  • Postman: приложение для тестирования REST-интерфейсов

  • Hoppscotch: веб-альтернатива Postman с открытым исходным кодом

Существует также множество публичных REST API, предназначенных для работы с анекдотами, конвертацией валют, геокодированием, государственными данными и всеми другими темами, которые только можно придумать. Многие из них бесплатны, хотя некоторые требуют регистрации ключа API или использования других методов аутентификации. Списки по категориям включают:

Попробуйте использовать некоторые RESTful API в своих проектах, прежде чем реализовывать собственные веб-сервисы. Или же можно пойти по стопам Facebook, GitHub, Google и многих других гигантов, создав собственный RESTful API.

FAQs About REST API

Что такое REST API?

REST API (Representational State Transfer Application Programming Interface) - это набор правил и соглашений, позволяющих программным приложениям общаться и взаимодействовать друг с другом через Интернет, используя принципы архитектурного стиля REST.

Каковы основные характеристики REST API?

Для REST API характерно использование ресурсов, безэталонное взаимодействие клиент-сервер, стандартные методы HTTP (GET, POST, PUT, DELETE) и унифицированные интерфейсы, которые обычно предполагают использование URL-адресов для доступа к ресурсам и работы с ними.

Почему API называется REST?

REST API (Representational State Transfer Application Programming Interface) назван в честь архитектурного стиля, которому он следует, известного как REST (Representational State Transfer). Термин “REST” был введен Роем Филдингом в его докторской диссертации 2000 года, где он изложил принципы и ограничения этого архитектурного стиля. Название “REST” означает концепцию передачи представления состояния ресурса от сервера к клиенту.

Каковы преимущества использования REST API?

REST API обладают рядом преимуществ, включая простоту, масштабируемость, легкость интеграции, независимость от платформы и разделение проблем. Кроме того, они используют существующую инфраструктуру HTTP и хорошо подходят для веб- и мобильных приложений.

Ограничиваются ли REST API только веб-приложениями?

Нет, REST API не ограничиваются веб-приложениями. Они могут использоваться для обеспечения взаимодействия между различными типами программных приложений, включая веб-приложения, мобильные приложения и даже межсерверные коммуникации.

Каковы четыре компонента REST API?

REST API состоит из четырех основных компонентов, которые часто называют “четырьмя столпами” REST. Эти компоненты помогают определить структуру, поведение и взаимодействие API в рамках архитектурного стиля REST. Этими четырьмя компонентами являются ресурсы, HTTP-методы (глаголы), представления и универсальный интерфейс.

Какие инструменты или библиотеки можно использовать для создания REST API?

Для создания REST API существует несколько инструментов и фреймворков, в том числе Express.js (Node.js), Flask (Python), Ruby on Rails (Ruby), Django (Python), Spring Boot (Java) и другие.

Связаться со мной

@gorlovfrontend