@xenterprises/fastify-xswagger
v1.1.1
Published
Fastify plugin for route-scoped Swagger documentation with access control
Readme
xSwagger
Fastify plugin for route-scoped Swagger documentation with access control and environment-aware behavior.
Features
- Route-scoped documentation: Generate separate Swagger docs for different route prefixes
- Access control: Public or private docs with Basic Auth protection
- Environment-aware: Disable documentation in production
- Multiple docs: Support multiple documentation instances (public API, admin API, etc.)
Installation
npm install xswagger @fastify/swagger @fastify/swagger-uiUsage
import Fastify from "fastify";
import xSwagger from "xswagger";
const fastify = Fastify();
// Register your routes first
fastify.get("/public/users", { schema: { tags: ["users"] } }, async () => ({ users: [] }));
fastify.get("/admin/users", { schema: { tags: ["admin"] } }, async () => ({ users: [] }));
// Register xSwagger
await fastify.register(xSwagger, {
docs: [
{ prefix: "/public", access: "public", title: "Public API", version: "1.0.0" },
{ prefix: "/admin", access: "private", title: "Admin API", version: "1.0.0" },
],
auth: {
username: process.env.DOCS_USER,
password: process.env.DOCS_PASSWORD,
},
disableInProduction: true,
});
await fastify.listen({ port: 3000 });After starting your server:
- Public API docs:
http://localhost:3000/public/documentation - Admin API docs:
http://localhost:3000/admin/documentation(requires auth)
Configuration Options
| Option | Type | Required | Default | Description |
|--------|------|----------|---------|-------------|
| docs | Array | Yes | - | Array of documentation configurations |
| docs[].prefix | string | Yes | - | Route prefix to document (e.g., /admin) |
| docs[].title | string | Yes | - | API documentation title |
| docs[].access | string | Yes | - | 'public' or 'private' |
| docs[].version | string | No | '1.0.0' | API version |
| docs[].description | string | No | - | API description |
| auth | Object | When private docs | - | Basic Auth credentials |
| auth.username | string | When private docs | - | Username for private docs |
| auth.password | string | When private docs | - | Password for private docs |
| disableInProduction | boolean|string | No | false | See environment controls below |
| docsPath | string | No | '/documentation' | Base path for docs UI |
| active | boolean | No | true | Enable/disable the plugin |
Environment Controls
The disableInProduction option controls documentation availability in production:
| Value | Development | Production |
|-------|-------------|------------|
| false | All docs enabled | All docs enabled |
| true | All docs enabled | All docs disabled |
| 'public' | All docs enabled | Only private docs enabled |
Production is detected when NODE_ENV === 'production'.
API
After registration, access the plugin via fastify.xswagger:
// Configuration
fastify.xswagger.config
// {
// docsPath: '/documentation',
// disableInProduction: false,
// docCount: 2,
// hasAuth: true,
// environment: 'development'
// }
// Access individual docs
fastify.xswagger.docs.public // /public prefix
fastify.xswagger.docs.admin // /admin prefix
// Each doc exposes:
fastify.xswagger.docs.admin.prefix // '/admin'
fastify.xswagger.docs.admin.access // 'private'
fastify.xswagger.docs.admin.title // 'Admin API'
fastify.xswagger.docs.admin.version // '1.0.0'
fastify.xswagger.docs.admin.uiPath // '/admin/documentation'
fastify.xswagger.docs.admin.specPath // '/admin/documentation/json'
fastify.xswagger.docs.admin.spec() // Returns OpenAPI spec objectRoute Schemas
For routes to appear in documentation, add schema definitions:
fastify.get('/public/users/:id', {
schema: {
description: 'Get a user by ID',
tags: ['users'],
params: {
type: 'object',
properties: {
id: { type: 'string', description: 'User ID' }
},
required: ['id']
},
response: {
200: {
type: 'object',
properties: {
id: { type: 'string' },
name: { type: 'string' }
}
}
}
}
}, async (request) => {
return { id: request.params.id, name: 'John' };
});Hiding Routes
To hide a route from documentation:
fastify.get('/internal/debug', {
schema: {
hide: true
}
}, handler);Complete Example
import Fastify from "fastify";
import xSwagger from "xswagger";
const fastify = Fastify({ logger: true });
// Public routes
fastify.get("/public/health", {
schema: {
description: "Health check endpoint",
tags: ["health"],
response: {
200: {
type: "object",
properties: {
status: { type: "string" }
}
}
}
}
}, async () => ({ status: "ok" }));
fastify.get("/public/products", {
schema: {
description: "List all products",
tags: ["products"],
querystring: {
type: "object",
properties: {
limit: { type: "integer", default: 10 }
}
},
response: {
200: {
type: "array",
items: {
type: "object",
properties: {
id: { type: "string" },
name: { type: "string" },
price: { type: "number" }
}
}
}
}
}
}, async (request) => {
return [{ id: "1", name: "Widget", price: 9.99 }];
});
// Admin routes
fastify.get("/admin/users", {
schema: {
description: "List all users (admin only)",
tags: ["admin", "users"],
response: {
200: {
type: "array",
items: {
type: "object",
properties: {
id: { type: "string" },
email: { type: "string" },
role: { type: "string" }
}
}
}
}
}
}, async () => {
return [{ id: "1", email: "[email protected]", role: "admin" }];
});
// Portal routes
fastify.get("/portal/dashboard", {
schema: {
description: "User dashboard",
tags: ["portal"],
response: {
200: {
type: "object",
properties: {
widgets: { type: "array", items: { type: "object" } }
}
}
}
}
}, async () => ({ widgets: [] }));
// Register xSwagger with multiple doc configs
await fastify.register(xSwagger, {
docs: [
{
prefix: "/public",
access: "public",
title: "Public API",
version: "1.0.0",
description: "Public endpoints available without authentication"
},
{
prefix: "/admin",
access: "private",
title: "Admin API",
version: "1.0.0",
description: "Administrative endpoints"
},
{
prefix: "/portal",
access: "private",
title: "Portal API",
version: "1.0.0",
description: "User portal endpoints"
}
],
auth: {
username: process.env.DOCS_USER || "admin",
password: process.env.DOCS_PASSWORD || "secret"
},
disableInProduction: "public" // Only public docs disabled in production
});
await fastify.listen({ port: 3000 });
console.log("Documentation available at:");
console.log("- Public: http://localhost:3000/public/documentation");
console.log("- Admin: http://localhost:3000/admin/documentation");
console.log("- Portal: http://localhost:3000/portal/documentation");Testing
npm testLicense
ISC
