Перейти к содержимому

Пример проекта

outry-example-gin — небольшой API магазина на Gin: логин, пользователи, заказы и асинхронная оплата. В папке api/ каждый роут описан .outry-файлом, и вместе они используют все возможности формата — это ещё и экскурсия.

  1. Установите CLI (другие платформы) и склонируйте проект:

    Окно терминала
    curl -fsSL https://raw.githubusercontent.com/1rowvy/outry/master/install.sh | sh
    git clone https://github.com/1rowvy/outry-example-gin && cd outry-example-gin
  2. Запустите сервис — он всё хранит в памяти, пароль администратора admin:

    Окно терминала
    go run . &
  3. Передайте Outry пароль. admin_password объявлен секретом в api/env.toml, поэтому берётся из хранилища паролей или переменной OUTRY_*, но не из файла:

    Окно терминала
    export OUTRY_ADMIN_PASSWORD=admin # или: outry secret set admin_password
  4. Запустите все запросы и сценарии:

    Окно терминала
    outry run api
    ✓ api/flows/checkout.outry Checkout flow
    ↳ CreateUser 201 0ms
    ↳ Login cached
    ↳ CreateOrder 201 0ms
    ↳ PayOrder 202 0ms
    ↳ WaitUntilPaid 200 1ms
    ✓ paid.body.total == 45.5
    ✓ paid.body.user_id == user.body.id
    → saved last_order
    …
    22 passed, 0 failed

    У DeleteUser стоит confirm: true, поэтому Outry спросит перед отправкой; --yes отвечает за вас.

Каждый созданный запрос знает свой обработчик (handler: s.CreateUser). Переименуйте поле структуры запроса в internal/model/model.go:

type CreateUser struct {
Name string `json:"name" binding:"required"` // full name
FullName string `json:"full_name" binding:"required"` // full name

outry check читает исходники Go — компилировать и запускать ничего не нужно:

api/v1/users/post.outry:17:8: error: required field `full_name` (string) is missing from body ← internal/api/users.go:13
api/v1/users/post.outry:17:10: error: body field `name` is not in model.CreateUser ← internal/api/users.go:13
14 files, 2 environments, 12 Go routes: 2 errors, 0 warnings; 2 fixable with `outry import go --fix`

outry import go . --fix перепишет тело. В пулл-реквесте workflow проекта (outry check --format github) покажет те же ошибки на изменённых строках. Добавьте роут — outry import go . создаст для него запрос с уже заполненными телом, query, заголовками и проверкой ответа.

Возможность Файл
Окружения, общие переменные, секрет, middleware → заголовки api/env.toml
Проверки статуса, полей, заголовков, времени; JSON Schema api/health.outry
Параметры со значениями по умолчанию, cache: 50m между прогонами, негативный тест api/auth/login/post.outry
Тело form, cookie jar, cookies.session api/auth/session.outry
Вызовы: Login().body.token, CreateUser().body.id, один раз за прогон api/v1/users/get-by-id.outry
Вызовы с аргументами, only: [dev], confirm: true api/v1/users/delete-by-id.outry
Загрузка файла через multipart api/v1/users/avatar/post.outry
let на уровне файла, uuid(), арифметика, all / map, save api/v1/orders/post.outry
query-параметры со значением null не отправляются api/v1/orders/get.outry
poll до подтверждения оплаты api/v1/orders/pay/post.outry
Сценарии; идемпотентный повтор с fresh api/flows/checkout.outry
Shape из структур Go, ужесточённые вручную api/shapes.outry
outry check и outry run в GitHub Actions .github/workflows/api.yml

Коллекция началась с outry init и outry import go .; потом запросы получили проверки, параметры и вызовы, часть файлов переехала — outry import всё равно узнаёт их по handler:.