Skip to content

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.

  • An OpenApiSpec filled by at least one controller’s attachToApp (see Document an API).
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.

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.

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 is
docsHandler(spec, specPath: 'spec.json'); // relative: resolved against the mount

openapi.json is still served by the handler either way.

docsHandler(
spec,
title: 'Acme API',
swaggerTitle: 'Acme API · Try it',
redocTitle: 'Acme API · Reference',
);
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.

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.

Terminal window
curl -si localhost:8080/docs | head -1 # HTTP/1.1 200 OK
curl -si localhost:8080/docs/ | grep -i location # location: /docs
curl -s localhost:8080/openapi.json | jq .info.title