revali_swagger generates an OpenAPI 3.0.3
spec from your controllers, parameters and return types. Use it to feed Swagger UI, Redoc, API gateways or client generators for languages other than Dart. For a Dart client, use
revali_client instead.
It is a generic construct, so the spec is rewritten on every revali dev (and revali build) run.
Installation#
| Package | Role | Section |
|---|---|---|
revali_swagger |
The construct (spec generator) | dev_dependencies |
revali_swagger_annotations |
Optional
annotations
(
@ApiSummary
,
@ApiTag
, ...)
|
dependencies |
dart pub add --dev revali_swagger
dart pub add revali_swagger_annotations # only if you use the annotations
dependencies:
revali_swagger_annotations: ^1.0.0
dev_dependencies:
revali: ^3.3.3
revali_swagger: ^1.3.0
No revali.yaml entry is required. Run:
dart run revali dev
The spec is written in both formats:
.revali/revali_swagger/
├── swagger.yaml
└── swagger.json
Types the generator cannot map are reported on stderr as [revali_swagger] WARNING: .... Fix them with
@ApiType.
Configuration#
All options are optional and go under the construct's entry in revali.yaml:
constructs:
- name: revali_swagger
options:
title: My API
version: 2.1.0
description: Public API for the My App service
| Option | Type | Default | Sets |
|---|---|---|---|
title |
String |
API |
info.title |
version |
String |
1.0.0 |
info.version |
description |
String |
none | info.description |
@ApiInfo on your app class overrides these values.
Example#
import 'package:revali_router/revali_router.dart';
@Controller('users')
class UsersController {
const UsersController();
@Get(':id')
Future<User> getById(@Param() String id) async => ...;
@Post()
@StatusCode(201)
Future<User> create(@Body() CreateUserBody body) async => ...;
}
produces (abridged):
openapi: 3.0.3
info:
title: API
version: 1.0.0
paths:
'/users':
post:
operationId: users_create
tags:
- users
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateUserBody'
responses:
'201':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'/users/{id}':
get:
operationId: users_getById
tags:
- users
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/User'
components:
schemas:
# User, CreateUserBody ...
How routes map to the spec#
-
Paths join the controller and method paths, with
:idrewritten as{id}. The app prefix (/apiby default) is not included, and the spec has noserversblock. Add both in your tooling if it needs them. -
Operation IDs are
<controller>_<method>, where<controller>is the class name withoutController, lowercased:UsersController.getByIdbecomesusers_getById. -
Tags default to that same lowercased controller name. Override them with
@ApiTag. -
Parameters:
@Parambecomesin: path,@Queryin: query,@Headerin: header,@Cookiein: cookie.@Bodybecomes therequestBody, except onGET,HEADandDELETE, where it is documented as a query parameter. -
Responses use the method's
@StatusCode, or200. Avoidhandler gets aNo contentresponse with no schema.@ApiResponsereplaces this default. -
Response schemas describe the handler's return type as-is. They do not include the
{"data": ...}envelope that Revali wraps JSON responses in. - Output is sorted by path and method, so the spec is stable across machines and safe to commit or diff.
See Type Inference for how Dart types become schemas, and Annotations to add summaries, descriptions and extra responses.