Как создать REST API: проектирование, безопасность и развёртывание
Чтобы создать REST API, перечислите ресурсы, которыми управляет ваше приложение (пользователи, заказы, бронирования), задайте каждому URL, например /orders и /orders/{id}, и используйте методы HTTP для действий: GET для чтения, POST для создания, PATCH для изменения, DELETE для удаления. Возвращайте JSON с понятными кодами состояния, проверяйте каждый входящий параметр, требуйте аутентификацию и проверку прав на каждую запись на сервере, а списки разбивайте на страницы. Затем задокументируйте эндпоинты и разверните API за HTTPS.
В этом руководстве рассматриваются проектные решения, пример набора маршрутов, промпты для ИИ-конструктора приложений и ошибки, которые создают дыры в безопасности. Если API для вас новое понятие, начните с что такое API.
Когда нужен REST API
- Веб-интерфейсу нужно сохранять и загружать данные с сервера
- Мобильному приложению, партнёру или инструменту автоматизации нужен доступ к вашим данным
- Другие сервисы присылают вам события (вебхуки)
- Работа распределена между командой фронтенда и командой бэкенда
REST — самый распространённый стиль, но не единственный. REST и GraphQL объясняет, когда лучше подходит один гибкий эндпоинт для запросов.
Сначала проектирование: ресурсы и маршруты
Запишите существительные вашего приложения и то, что люди делают с ними. Для простого приложения бронирования:
| Метод | Маршрут | Что делает | Код успеха |
|---|---|---|---|
GET | /api/bookings | Список бронирований вызывающего (с пагинацией) | 200 |
POST | /api/bookings | Создать бронирование | 201 |
GET | /api/bookings/{id} | Получить одно бронирование | 200 |
PATCH | /api/bookings/{id} | Изменить некоторые поля | 200 |
DELETE | /api/bookings/{id} | Отменить бронирование | 204 |
GET | /api/health | Проверка работоспособности для мониторинга | 200 |
Эти маршруты соответствуют операциям создания, чтения, изменения и удаления; см. что такое CRUD. Полезные соглашения:
- Существительные во множественном числе, без глаголов в URL:
/bookings, а не/getBookings. - Вложенность только на один уровень, если это проясняет принадлежность:
/bookings/{id}/notes. - Действия, не относящиеся к CRUD, можно оформить как подресурсы:
POST /bookings/{id}/cancelпонятнее, чем PATCH с неочевидным смыслом. - Единое именование полей, например
created_atвезде.
Коды состояния и ошибки
Используйте стандартные коды HTTP, чтобы клиенты понимали результат без разбора текста:
| Код | Значение | Когда использовать |
|---|---|---|
| 200 | OK | Успешное чтение или изменение |
| 201 | Created | POST создал что-то |
| 204 | No Content | Успех без данных в ответе |
| 400 | Bad Request | Ввод не прошёл валидацию |
| 401 | Unauthorized | Не выполнен вход или неверный токен |
| 403 | Forbidden | Вход выполнен, но доступ запрещён |
| 404 | Not Found | Не существует или вызывающий не должен знать, что она есть |
| 409 | Conflict | Дубликат или слот уже занят |
| 429 | Too Many Requests | Превышен лимит запросов |
| 500 | Server Error | На вашей стороне что-то сломалось |
Возвращайте ошибки в одном и том же формате JSON, например {"error": {"code": "slot_taken", "message": "Это время уже недоступно."}}, и никогда не включайте в ответы трассировки стека или ошибки базы данных.
Варианты и компромиссы
| Решение | Простой выбор | Альтернатива |
|---|---|---|
| Где живёт API | API-маршруты в вашем веб-фреймворке | Отдельный API-сервис, полезный для нескольких клиентов или другого языка |
| Аутентификация | Сессионные cookie для вашего веб-приложения | Токены (bearer-токены или ключи API) для мобильных приложений и сторонних сервисов |
| Пагинация | ?page=2&limit=20 | Курсорная (?after=...), стабильнее для больших изменяющихся списков |
| Версионирование | Не нужно, пока нет внешних пользователей | /v1/ в пути, когда от него зависят другие |
| Документация | README со списком маршрутов | Спецификация OpenAPI, по которой инструменты создают интерактивную документацию и клиентский код |
Пошагово
- Перечислите ресурсы и маршруты, как описано выше, включая то, кто может вызывать каждый из них.
- Смоделируйте данные в базе с нужными полями и связями.
- Сначала создайте маршруты чтения, затем создание, изменение и удаление.
- Валидируйте входящие данные при каждой записи с помощью библиотеки схем: обязательные поля, типы, длина, допустимые значения. Отклоняйте неизвестные поля.
- Добавьте аутентификацию, затем авторизацию для каждой записи: загрузка
/bookings/42должна проверять, что бронирование 42 принадлежит вызывающему, а не только то, что пользователь вошёл в систему. - Разбивайте на страницы каждый список и ограничивайте размер страницы.
- Ограничивайте частоту запросов для входа и дорогостоящих маршрутов. См. ограничение частоты запросов.
- Настраивайте CORS только если браузеры с других доменов должны обращаться к API, и явно перечисляйте эти источники. Как исправить ошибки CORS объясняет ошибки, которые вы увидите.
- Напишите документацию и тесты для каждого маршрута, включая случаи ошибок.
- Разверните с секретами в переменных окружения, HTTPS, логами и проверкой работоспособности.
Промпты для ИИ-конструктора
Каркас:
Создай REST API для бронирований со следующими маршрутами: GET /api/health, GET /api/bookings (с пагинацией, не больше 50 на страницу), POST /api/bookings, GET /api/bookings/:id, PATCH /api/bookings/:id, DELETE /api/bookings/:id. Храни данные в нашей базе данных. Валидируй тела запросов с помощью библиотеки схем и отклоняй неизвестные поля. Возвращай ошибки в JSON вида {"error": {"code", "message"}} с правильными кодами состояния (400, 401, 403, 404, 409). Храни секреты в переменных окружения.
Безопасность:
Требуй вход для каждого маршрута бронирований. При каждом чтении, изменении и удалении проверяй на сервере, что бронирование принадлежит текущему пользователю; если нет, возвращай 404. Никогда не принимай ID пользователя или роли из тела запроса. Ограничь POST /api/bookings до 20 запросов в минуту на пользователя. Записывай ошибки в лог на сервере, не возвращая трассировки стека.
Документация:
Напиши описание этих маршрутов в формате OpenAPI и короткий README с примерами запросов и ответов для каждого маршрута.
Тестирование API
Тестируйте API извне фронтенда, потому что злоумышленники будут делать именно так:
- Каждый маршрут работает с корректными данными и возвращает описанную структуру и код
- Отсутствующие или неверные поля возвращают 400 с понятным сообщением
- Отсутствие токена возвращает 401 на каждом защищённом маршруте
- Пользователь A, запрашивающий запись пользователя B по ID, получает 404 или 403
- Списки разбиты на страницы; очень большой
limitограничивается - Повторяющиеся или конфликтующие создания возвращают 409, а не 500
- Превышение лимитов возвращает 429
- Ответы с ошибками не содержат трассировок стека, SQL или секретов
- CORS разрешает только задуманные источники
Частые ошибки
- Проверка входа без проверки владельца. Самая распространённая дыра в API: любой вошедший пользователь может прочитать любую запись, поменяв ID.
- Доверие клиенту. Цены, роли и ID пользователей из тела запроса можно подменить.
- Возврат целых строк базы данных. Хеши паролей и внутренние поля утекают. Выбирайте, что входит в каждый ответ.
- Списки без ограничения. Один запрос на все записи может замедлить всё приложение.
200 OKс текстом ошибки внутри. Клиенты и мониторинг не поймут, что запрос провалился.- CORS, разрешающий всё, для API, который использует cookie.
- Нет проверки работоспособности и логов, поэтому о сбоях вы узнаёте от пользователей.
Для более широкой проверки перед запуском см. чек-лист безопасности для приложений, созданных с ИИ.
Создание REST API в Mythex
Вы можете попросить Mythex создать API как часть приложения или как отдельный сервис. В документации рецепт REST API backend содержит стартовый промпт: назовите фреймворк и маршруты, попросите понятные JSON-ошибки, храните секреты в переменных окружения и добавьте Dockerfile. Контейнерные бэкенды на Node, Python, C#, Java и других публикуются через Dockerfile, а развёртывание из Publish Mythex берёт на себя (API-бэкенды). Проект может одновременно содержать сайт и API-сервер, и вы можете переключаться между ними в предпросмотре. Ключи храните как секреты проекта; если API нужна база данных, попросите её в чате. Для регулярных задач вокруг API см. как запускать фоновые задачи.
Вопросы
Что такое REST API?
REST API — это способ, с помощью которого программы работают с данными вашего приложения по HTTP. Каждый тип данных — это ресурс с собственным URL, например /orders, а стандартные методы выполняют действия над ним: GET для чтения, POST для создания, PATCH или PUT для изменения и DELETE для удаления. Данные обычно передаются в формате JSON.
На каком языке писать REST API?
Выбирайте тот, который вы или ваша команда сможете поддерживать. Node.js с Express или Fastify, Python с FastAPI и фреймворки на C# или Java подходят одинаково хорошо. Правила проектирования маршрутов, кодов ответа, валидации и аутентификации важнее языка.
Как защитить REST API?
Требуйте аутентификацию для каждого маршрута, кроме публичных, проверяйте на сервере, что вызывающий может получить доступ к конкретной записи, валидируйте весь входящий ввод, используйте HTTPS, ограничивайте число запросов и храните секреты в переменных окружения. Никогда не доверяйте ID или ролям, которые передал клиент.
Нужен ли отдельный бэкенд для REST API?
Не всегда. Фреймворки вроде Next.js могут обслуживать API-маршруты рядом со страницами. Отдельный API-сервис имеет смысл, когда им пользуются несколько клиентов (веб, мобильные приложения, партнёры) или когда ему нужны собственный язык или масштабирование.