Svelte

API-эндпоинты: +server.js

Мобильное приложение и сторонний сервис должны дёргать тот же бэкенд, что и сайт - им нужен чистый JSON, а не HTML-страница с формой. Form action привязан к конкретной странице и возвращает результат в проп form, это не подходит для программного клиента. SvelteKit решает это файлом +server.js: он определяет настоящий HTTP-эндпоинт с обработчиками GET, POST, PUT, DELETE, который принимает стандартный Request и отдаёт стандартный Response. Тот же роутинг, что и у страниц, но на выходе данные, а не разметка.

  • JSON-API для мобильного приложения: GET /api/products отдаёт каталог тем же кодом, что использует сайт
  • Вебхук от платёжного провайдера: POST /api/webhooks/stripe принимает событие и проверяет подпись
  • Эндпоинт выгрузки: GET /api/report.csv возвращает файл с нужными заголовками Content-Type
  • Health-check для оркестратора: GET /api/health отдаёт 200 и статус сервиса для Kubernetes-проб
  • Загрузка изображений: POST /api/upload принимает multipart и кладёт файл в хранилище

Предварительные знания

  • Файловый роутинг SvelteKit и структура папки routes
  • HTTP-методы GET, POST, PUT, DELETE и коды статусов
  • Веб-стандарты Request и Response (Fetch API), формат JSON

Обработчики методов и Response

Файл +server.js в папке маршрута превращает этот путь в HTTP-эндпоинт. Вместо одной функции load экспортируется по функции на каждый поддерживаемый метод: GET, POST, PUT, PATCH, DELETE. Имя экспорта - это имя HTTP-метода заглавными буквами. Каждый обработчик возвращает стандартный объект Response.

Хелпер json() из @sveltejs/kit берёт любое сериализуемое значение и возвращает Response с телом в формате JSON и проставленным заголовком Content-Type application/json. Это короче, чем вручную создавать new Response(JSON.stringify(...)) и выставлять заголовки. Вторым аргументом json() принимает init с полями status и headers.

Обработчик не обязан возвращать JSON. Можно вернуть голый Response с любым телом и Content-Type: text/csv для выгрузки, image/png для картинки, text/plain для простого текста. json() - лишь частый и удобный случай, а не единственный способ.

Как в +server.js объявить обработчик, отвечающий на HTTP-запросы методом GET?

Чтение Request и обработка POST

Обработчик POST читает тело запроса через стандартный объект Request, который лежит в event.request. Для JSON-тела вызывают request.json(), для данных формы request.formData(), для произвольного текста request.text(). Эти методы возвращают промис, поэтому их await-ят. Это те же веб-стандарты, что в браузерном Fetch API, без отдельного фреймворкового слоя.

Внутри эндпоинта доступен тот же event, что и в load: params для динамических сегментов, url для строки запроса, locals для пользователя и сессии. Функция error из @sveltejs/kit формирует HTTP-ошибку с нужным статусом - 401 без авторизации, 400 при некорректном теле, 404 для ненайденного ресурса. Для созданной сущности принято возвращать статус 201.

Тело запроса можно прочитать только один раз: после await request.json() повторный вызов request.text() упадёт, потому что поток уже израсходован. Если нужно и то и другое, сначала читают text(), а затем парсят строку самостоятельно.

Клиент отправил POST с JSON-телом. Как прочитать это тело внутри обработчика POST в +server.js?

Когда +server.js, а когда form action

И form action, и POST в +server.js выполняют запись на сервере, поэтому выбор между ними иногда путает. Решает то, кто и как обращается к серверу. Form action заточен под форму конкретной страницы: он встроен в прогрессивное улучшение, возвращает результат в проп form и сам перезапускает load. +server.js - это переиспользуемый HTTP-эндпоинт для любого клиента: мобильного приложения, стороннего сервиса, вебхука, fetch из JS.

КритерийForm action+server.js
Кто вызываетФорма на той же страницеЛюбой клиент: app, сервис, вебхук, fetch
Без JavaScriptРаботает нативно через POST формыНет, нужен программный запрос
Что возвращаетДанные в проп form, перезапуск loadПроизвольный Response: JSON, файл, текст
МетодыТолько POSTGET, POST, PUT, PATCH, DELETE
Типичный случайЛогин, корзина, настройки на страницеПубличный API, вебхуки, выгрузки, GET-данные

Практичное правило: если запись инициирует видимая на странице форма и важна работа без JS, берут form action. Если нужен метод кроме POST, доступ из внешних клиентов, формат ответа кроме страничного form или просто чистый JSON-контракт - берут +server.js. Один маршрут не может одновременно иметь +page.server.js с actions и +server.js, поэтому выбор делают сознательно.

Если эндпоинт нужен и сайту, и мобильному приложению, разумно держать всю логику записи в +server.js, а форма страницы будет дёргать его через use:enhance или обычный fetch. Так бизнес-логика не дублируется между action и эндпоинтом.

Мобильное приложение и веб-сайт должны создавать заказы через один и тот же серверный код, отдающий JSON. Что выбрать?

Связь с другими темами

+server.js - программный слой HTTP. Он соседствует с формами и загрузкой:

  • Form actions — Альтернатива для записи, привязанная к странице и форме; +server.js нужен для программных клиентов
  • Load-функции — Universal load обращается к +server.js эндпоинтам через свой fetch для получения данных
  • Hooks — Эндпоинт берёт авторизацию из event.locals, заполненных серверным handle до его вызова

Итог

  • Файл +server.js определяет HTTP-эндпоинт; имена экспортов совпадают с методами: GET, POST, PUT, DELETE, PATCH
  • Обработчик получает event с теми же params, url, request, locals, что и load, и возвращает объект Response
  • Хелпер json() из @sveltejs/kit оборачивает данные в Response с заголовком Content-Type application/json
  • Тело POST читают через стандартные методы Request: request.json(), request.formData(), request.text()
  • Form action выбирают для форм страницы; +server.js - для программного API, вебхуков, файлов и сторонних клиентов

Связанные уроки

  • sv-20-form-actions — Form actions и +server.js оба пишут данные на сервере; урок проводит границу, когда уместен каждый из них
  • sv-19-load-functions — Universal load часто дергает именно такой +server.js эндпоинт через переданный fetch
  • sv-22-hooks — Эндпоинт читает пользователя и сессию из event.locals, которые наполняет серверный handle
API-эндпоинты: +server.js

0

1

Войти