Topazdocs
Создание приложений

Ограниченный HTTP-сервис

Сборка, запуск и развёртывание проверенного сервиса Topaz HTTP/1.1 с явными ограничениями.

Цель http-service превращает один проверенный обработчик Topaz в управляемый нативный сервис HTTP/1.1. Сгенерированный хост отвечает за listener, HTTP framing, сроки выполнения, перегрузку, журналирование и завершение работы. Код Topaz получает HttpRequest и возвращает HttpResponse.

Это намеренно ограниченный хост, а не универсальный Web framework. Он не добавляет исходящие сетевые запросы, сокеты, TLS, HTTP/2, WebSocket, сессии, общее изменяемое состояние приложения, неявный доступ к переменным окружения или синтаксис async/await. Для публичного TLS и политики внешней границы поставьте перед процессом обычный reverse proxy.

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

BASH
topaz init --target http-service --root hello-service
topaz fmt --root hello-service --check
topaz check --root hello-service
topaz test --root hello-service

Entry-модуль экспортирует ровно один конкретный обработчик следующего типа:

TOPAZ
import std.http { HttpRequest, HttpResponse, text }

export function handle(req: HttpRequest) -> HttpResponse {
  if req.method == "GET" && req.url.path() == "/health" {
    return text(200, "ok")
  }
  text(404, "not found")
}

Если handle отсутствует, является generic или variadic, имеет параметры по умолчанию либо другой тип запроса или ответа, проверка завершается до открытия listener.

Разработка через настоящий loopback HTTP

BASH
topaz dev --root hello-service --port 8080
curl --fail-with-body http://127.0.0.1:8080/health

topaz dev всегда заменяет адрес привязки на 127.0.0.1. Команда собирает тот же управляемый исполняемый файл, который используется при развёртывании, и передаёт ему прерывание, поэтому Ctrl-C проверяет настоящий путь завершения.

Конечные бюджеты

Раздел [service] отклоняет неизвестные ключи и значения вне допустимых диапазонов. Эти значения по умолчанию входят в контракт сгенерированного продукта:

TOML
[service]
bind = "127.0.0.1"
port = 8080
workers = 1
max_connections = 64
queue_capacity = 32
max_target_bytes = 8192
max_header_bytes = 16384
max_headers = 64
max_body_bytes = 1048576
header_timeout_ms = 5000
body_timeout_ms = 5000
handler_timeout_ms = 1000
shutdown_grace_ms = 5000
log_format = "text"

workers задаёт ограниченную ёмкость одновременно выполняемых обработчиков на однопоточном reactor. Каждый запрос получает новый runtime context и граф модулей; запросы не разделяют heap Topaz. При превышении срока cooperative-обработчика его future удаляется, а ёмкость снова доступна. Потенциально бесконечные сгенерированные циклы содержат точки отмены, а синхронные операции ограничены допустимым размером входа.

Исполняемый файл принимает те же параметры в виде флагов kebab-case. В manifest разрешён только loopback IP. Другой адрес для собранного сервиса необходимо указать явным аргументом процесса:

BASH
./target/release/program --bind 0.0.0.0 --port 8080

Итоговую проверенную конфигурацию с учётом параметров командной строки можно посмотреть, не открывая сетевой порт:

BASH
./target/release/program --port 9090 --workers 2 --print-config

Команда печатает один объект JSON со схемой topaz.httpServiceConfig.v1. Управляемый файл topaz-service-config.json хранит в той же схеме встроенные значения, а --print-config показывает итоговые параметры процесса. Неизвестные, повторные, некорректные или выходящие за допустимый диапазон параметры отклоняются до привязки порта.

Сборка и копирование продукта

BASH
topaz build --root hello-service --locked --release --out-dir hello-service-product
cp -R hello-service-product /srv/hello-service
cd /srv/hello-service
./target/release/program --help
./target/release/program

Управляемый каталог содержит нативный исполняемый файл, topaz-service-config.json, уведомления сторонних компонентов, лицензию и уведомления Topaz, а также topaz-artifact.json. Во время запуска бинарному файлу не нужны исходники пакета, checkout Topaz, реестр Cargo или временная рабочая область сборки. Копируйте каталог целиком, чтобы метаданные целостности и уведомления оставались рядом с программой.

Ошибки и наблюдаемость

  • Слишком большое тело даёт 413, слишком длинная цель запроса — 414, слишком большой набор заголовков — 431, если HTTP framing позволяет отправить ответ.
  • Переполненная очередь обработчиков даёт 503 с Connection: close.
  • Превышение срока обработчика даёт обобщённый 504 и освобождает worker capacity.
  • Runtime fault и недопустимый ответ превращаются в обобщённый 500 без раскрытия путей исходников, тела запроса, значений заголовков или сообщения fault Topaz.
  • Ответ содержит x-topaz-request-id. Текстовый журнал или JSON со схемой topaz.httpServiceLog.v1 содержит тот же идентификатор, ограниченный код, статус или локальную диагностику, но не цель запроса, тело и значения заголовков.
  • Журнал различает service-started, shutdown-requested, shutdown-complete и shutdown-forced. Значение log_format = "off" отключает журналы сервиса, но явный вывод --print-config остаётся доступным.
  • SIGINT, а в Unix также SIGTERM, прекращает приём новых соединений, ждёт существующие не дольше shutdown_grace_ms и фиксирует штатное или принудительное завершение.

Хост проверяет статус и синтаксис заголовков и сам владеет Content-Length, transfer encoding и hop-by-hop заголовками. Ответ приложения не может переопределить эти транспортные поля.

Граница развёртывания

Запускайте программу под process supervisor. Завершайте TLS и новые версии HTTP на reverse proxy, передавайте обычный HTTP/1.1 на настроенный адрес сервиса, сохраняйте ограничения тела, заголовков и сроков. Используйте /health только с тем смыслом готовности, который действительно реализован обработчиком Topaz. Скопированный артефакт предыдущего публичного minor-релиза служит единицей rollback; изменение конфигурации не переписывает управляемые байты.