Serve the docs UI
You will mount docsHandler so that your app
serves openapi.json, Swagger UI and Redoc, move them under a prefix, and switch them off in
production.
Prerequisites
Section titled “Prerequisites”- An
OpenApiSpecfilled by at least one controller’sattachToApp(see Document an API).
1. Mount at the root
Section titled “1. Mount at the root”import 'package:gisila_doc/gisila_doc.dart';
app.registerController(attacher: (app, router, {String prefix = ''}) { UsersController().attachToApp(app, router, spec, prefix: prefix); router.mount('/', docsHandler(spec));});This serves:
| URL | Content |
|---|---|
/openapi.json |
The document |
/docs |
Swagger UI |
/redoc |
Redoc |
Mount the docs after the controllers. Routes are matched in registration order, so your routes win over the docs mount.
2. Or mount under a prefix
Section titled “2. Or mount under a prefix”router.mount('/api-docs/', docsHandler(spec, title: 'Acme API'));Now the pages are /api-docs/docs, /api-docs/redoc and /api-docs/openapi.json. Links and the
spec URL are computed from the mount point, so nothing else changes. /api-docs/docs/ redirects
to /api-docs/docs.
3. Point the UIs at a different spec URL
Section titled “3. Point the UIs at a different spec URL”If a proxy or CDN serves the spec from somewhere else, pass specPath:
docsHandler(spec, specPath: 'https://cdn.example.com/acme/openapi.json');docsHandler(spec, specPath: '/v1/openapi.json'); // absolute path, used as isdocsHandler(spec, specPath: 'spec.json'); // relative: resolved against the mountopenapi.json is still served by the handler either way.
4. Set titles
Section titled “4. Set titles”docsHandler( spec, title: 'Acme API', swaggerTitle: 'Acme API · Try it', redocTitle: 'Acme API · Reference',);5. Turn the docs off in production
Section titled “5. Turn the docs off in production”import 'dart:io';
final docsEnabled = Platform.environment['APP_ENV'] != 'production';router.mount('/', docsHandler(spec, enabled: docsEnabled));With enabled: false every docs route, including openapi.json, answers 404. If you only want
to hide the UIs but keep the spec for client generation, mount a handler for openapi.json
yourself:
router.get('/openapi.json', (Request _) => Response.ok( spec.toJson(), headers: {'content-type': 'application/json; charset=utf-8'}, ));Alternatively, guard the docs mount with your own middleware (for example basic auth) using a
Shelf Pipeline.
6. Know what loads from where
Section titled “6. Know what loads from where”The UI pages pull Swagger UI 5.33.1 and Redoc 2.5.4 from unpkg.com, pinned with Subresource
Integrity. The browser of whoever opens the docs needs to reach unpkg; if it can’t (air-gapped
networks, strict CSP), serve spec.toJson() and host a UI yourself.
Verify it works
Section titled “Verify it works”curl -si localhost:8080/docs | head -1 # HTTP/1.1 200 OKcurl -si localhost:8080/docs/ | grep -i location # location: /docscurl -s localhost:8080/openapi.json | jq .info.title