Example project
outry-example-gin is a small shop API written with
Gin: login, users, orders and asynchronous payments. Its api/ folder
describes every route in .outry files and uses every feature of the format, so it doubles as a tour.
Run it
Section titled “Run it”-
Install the CLI (other platforms) and clone the project:
Terminal window curl -fsSL https://raw.githubusercontent.com/1rowvy/outry/master/install.sh | shgit clone https://github.com/1rowvy/outry-example-gin && cd outry-example-gin -
Start the service — it keeps everything in memory, the admin password is
admin:Terminal window go run . & -
Give Outry the password.
admin_passwordis declared as a secret inapi/env.toml, so it comes from the keychain or aOUTRY_*variable, never from a file:Terminal window export OUTRY_ADMIN_PASSWORD=admin # or: outry secret set admin_password -
Run every request and flow:
Terminal window 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 failedDeleteUserhasconfirm: true, so Outry asks before sending it;--yesanswers for you.
Change the code
Section titled “Change the code”Every generated request knows its handler (handler: s.CreateUser). Rename a field of the request
struct in internal/model/model.go:
type CreateUser struct { Name string `json:"name" binding:"required"` // full name FullName string `json:"full_name" binding:"required"` // full nameoutry check reads the Go source — nothing has to compile or run:
api/v1/users/post.outry:17:8: error: required field `full_name` (string) is missing from body ← internal/api/users.go:13api/v1/users/post.outry:17:10: error: body field `name` is not in model.CreateUser ← internal/api/users.go:1314 files, 2 environments, 12 Go routes: 2 errors, 0 warnings; 2 fixable with `outry import go --fix`outry import go . --fix rewrites the body. In a pull request the project’s workflow
(outry check --format github) puts the same errors on the changed lines. Add a route, and
outry import go . creates its request with the body, query, headers and a response check filled in.
What is where
Section titled “What is where”| Feature | File |
|---|---|
| Environments, shared variables, a secret, middleware → headers | api/env.toml |
| Checks of status, fields, headers, timing; a JSON Schema | api/health.outry |
Parameters with defaults, cache: 50m between runs, a negative test |
api/auth/login/post.outry |
form body, the cookie jar, cookies.session |
api/auth/session.outry |
Calls: Login().body.token, CreateUser().body.id, sent once per run |
api/v1/users/get-by-id.outry |
Calls with arguments, only: [dev], confirm: true |
api/v1/users/delete-by-id.outry |
multipart file upload |
api/v1/users/avatar/post.outry |
File-level let, uuid(), arithmetic, all / map, save |
api/v1/orders/post.outry |
null query parameters left out |
api/v1/orders/get.outry |
poll until the payment is confirmed |
api/v1/orders/pay/post.outry |
Flows; an idempotent retry with fresh |
api/flows/checkout.outry |
| Shapes from Go structs, made stricter by hand | api/shapes.outry |
outry check and outry run in GitHub Actions |
.github/workflows/api.yml |
The collection started as outry init and outry import go .; the requests then got checks, parameters
and calls, and some files were moved — outry import still recognizes them by handler:.