@sleeksky/alt-swagger
v3.1.0
Published
A fluent, programmatic API for generating OpenAPI 3.0 specifications with TypeScript support. Define REST API endpoints, schemas, parameters, and security using a simple, chainable syntax.
Readme
Alt Swagger
A fluent, programmatic API for generating OpenAPI 3.0 specifications. Quickly define your REST API endpoints with request/response schemas, parameters, security, and more using a simple, chainable syntax.
Built on top of @sleeksky/alt-schema for intuitive JSON schema definitions.
Features
- 🚀 Fluent API: Chain methods to define endpoints declaratively
- 📝 Schema-first: Define request/response schemas using simple string syntax
- 🔒 Security: Built-in support for authentication schemes
- 🏷️ Rich Metadata: Tags, summaries, descriptions, deprecation
- 🔄 Reusable Schemas: Define and reference schemas across endpoints
- 🎯 TypeScript Support: Full TypeScript definitions included
- 📊 OpenAPI 3.0: Generates valid OpenAPI 3.0 specifications
Installation
npm install @sleeksky/alt-swagger
# or
yarn add @sleeksky/alt-swagger
# or
pnpm add @sleeksky/alt-swaggerQuick Start
const swagger = require('@sleeksky/alt-swagger');
// Define your API
swagger.server('https://api.example.com', 'Production API');
// Define endpoints
swagger.get('/users')
.summary('Get users')
.query('limit:i:10,offset:i:0')
.res(200, '[{id:i,name:s,email:s}]');
swagger.post('/users')
.summary('Create user')
.req('{name:s,email:s}')
.res(201, '{id:i,name:s,email:s}')
.res(400, '{error:s}');
// Generate OpenAPI spec
const spec = swagger.swaggerDoc('User API', '1.0.0');
console.log(JSON.stringify(spec, null, 2));Schema Syntax
Alt Swagger uses a compact string syntax for defining JSON schemas, powered by alt-schema:
Basic Types
s- stringi- integern- numberb- booleano- objecta- array
Examples
// Simple object
'{name:s, age:i}'
// With default values
'{name:s:John, age:i:25}'
// Optional fields (prefixed with ?)
'{name:s, age:?i, email:?s}'
// Nested objects
'{user:{name:s, age:i}, active:b}'
// Arrays
'[{id:i, name:s}]'
// Complex nested structure
'{id:i, profile:{name:s, settings:{theme:s:dark, notifications:b:true}}}'API Reference
Core Methods
swagger.server(url, description?)
Define API servers.
swagger.server('https://api.example.com', 'Production');
swagger.server('https://staging.api.example.com', 'Staging');swagger.tag(name, description?)
Define tags for grouping endpoints.
swagger.tag('Users', 'User management endpoints');
swagger.tag('Posts', 'Blog post endpoints');HTTP Methods
All HTTP methods return a fluent API for chaining:
swagger.get(path)
swagger.post(path)
swagger.put(path)
swagger.patch(path)
swagger.del(path) (or swagger.delete(path))
swagger.get('/users/{id}')
.summary('Get user by ID')
.res(200, '{id:i, name:s, email:s}')
.res(404, '{error:s}');Path Parameters
Parameters in curly braces are automatically detected:
// /users/{id} automatically creates path parameter 'id'
swagger.get('/users/{id}')
.res(200, '{id:i, name:s}');
// With default values
swagger.get('/users/{id:123}')
.res(200, '{id:i, name:s}');Fluent API Methods
.req(schema)
Define request body schema.
swagger.post('/users')
.req('{name:s, email:s, age:?i}')
.res(201, '{id:i, name:s, email:s}');.res(statusCode, schema)
Define response schema for a status code.
swagger.get('/users')
.res(200, '[{id:i, name:s}]')
.res(404, '{error:s}')
.res(500, '{error:s, code:i}');.query(params)
Add query parameters. Accepts string or array.
// Single parameter
swagger.get('/users').query('limit:i:10');
// Multiple parameters (comma-separated)
swagger.get('/users').query('limit:i:10,offset:i:0');
// Array format
swagger.get('/users').query(['limit:i:10', 'offset:i:0']);
// Optional parameters
swagger.get('/users').query('search:?s');.header(params)
Add header parameters.
swagger.get('/users')
.header('authorization')
.header('x-api-key:?');.tag(name)
Add tags to the endpoint.
swagger.get('/users')
.tag('Users')
.tag('Public');.summary(text)
Add summary to the endpoint.
swagger.get('/users')
.summary('Retrieve a list of users');.desc(text) or .description(text)
Add description to the endpoint.
swagger.get('/users')
.desc('Returns a paginated list of users with optional filtering');.security(name)
Apply security scheme to the endpoint.
swagger.get('/users')
.security('bearerAuth');.deprecate()
Mark endpoint as deprecated.
swagger.get('/old-endpoint')
.deprecate()
.res(200, '{message:s}');Schema Management
swagger.ref.schema(name, schema)
Define reusable schemas.
const userSchema = swagger.ref.schema('User', '{id:i, name:s, email:s}');
const errorSchema = swagger.ref.schema('Error', '{error:s, code:i}');
swagger.get('/users')
.res(200, userSchema)
.res(500, errorSchema);Security
swagger.security(name, options?)
Define security schemes.
// Bearer token
swagger.security('bearerAuth');
// API Key
swagger.security('apiKey', {
type: 'apiKey',
in: 'header',
name: 'X-API-Key'
});
// Basic auth
swagger.security('basicAuth', {
type: 'http',
scheme: 'basic'
});Document Generation
swagger.swaggerDoc(title?, version?)
Generate the complete OpenAPI specification.
const spec = swagger.swaggerDoc('My API', '1.0.0');
// Returns OpenAPI 3.0 compliant objectUtility Methods
swagger.reset()
Clear all defined specifications.
swagger.reset(); // Start freshswagger.remove(options)
Remove endpoints.
// Remove specific path
swagger.remove({ path: '/users' });
// Remove by tag
swagger.remove({ tag: 'Deprecated' });Complete Examples
Basic CRUD API
const swagger = require('@sleeksky/alt-swagger');
swagger.server('https://api.example.com', 'User Management API');
swagger.tag('Users', 'User operations');
// Define schemas
const userSchema = swagger.ref.schema('User', '{id:i, name:s, email:s, created_at:s}');
const createUserSchema = swagger.ref.schema('CreateUser', '{name:s, email:s}');
const errorSchema = swagger.ref.schema('Error', '{error:s, code:i}');
// Security
swagger.security('bearerAuth');
// Endpoints
swagger.get('/users')
.tag('Users')
.summary('List users')
.security('bearerAuth')
.query('limit:?i:10,offset:?i:0')
.res(200, `[${userSchema}]`)
.res(401, errorSchema);
swagger.post('/users')
.tag('Users')
.summary('Create user')
.req(createUserSchema)
.res(201, userSchema)
.res(400, errorSchema);
swagger.get('/users/{id}')
.tag('Users')
.summary('Get user by ID')
.security('bearerAuth')
.res(200, userSchema)
.res(404, errorSchema);
swagger.put('/users/{id}')
.tag('Users')
.summary('Update user')
.security('bearerAuth')
.req(createUserSchema)
.res(200, userSchema)
.res(400, errorSchema)
.res(404, errorSchema);
swagger.del('/users/{id}')
.tag('Users')
.summary('Delete user')
.security('bearerAuth')
.res(204)
.res(404, errorSchema);
const spec = swagger.swaggerDoc('User API', '1.0.0');Express Integration
const express = require('express');
const swaggerUi = require('swagger-ui-express');
const swagger = require('@sleeksky/alt-swagger');
const app = express();
// Define API spec
swagger.server('http://localhost:3000', 'Local API');
swagger.get('/health')
.summary('Health check')
.res(200, '{status:s, timestamp:s}');
swagger.get('/users/{id}')
.summary('Get user')
.res(200, '{id:i, name:s}');
// Serve Swagger UI
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swagger.swaggerDoc('My API')));
// API routes
app.get('/health', (req, res) => {
res.json({ status: 'ok', timestamp: new Date().toISOString() });
});
app.get('/users/:id', (req, res) => {
const user = { id: parseInt(req.params.id), name: 'John Doe' };
res.json(user);
});
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
console.log('API docs at http://localhost:3000/api-docs');
});Advanced Schema Examples
const swagger = require('@sleeksky/alt-swagger');
// Complex nested schemas
const profileSchema = swagger.ref.schema('Profile', `
{
personal: {
firstName: s,
lastName: s,
age: ?i,
email: s
},
preferences: {
theme: s:light,
notifications: {
email: b:true,
push: b:false
}
},
tags: [s]
}
`);
// Array responses
swagger.get('/posts')
.summary('Get blog posts')
.query('category:?s,tag:?s,published:?b:true')
.res(200, `
[{
id: i,
title: s,
content: s,
author: {id:i, name:s},
tags: [s],
published: b,
created_at: s
}]
`);
// Union-like responses (use oneOf in OpenAPI)
swagger.post('/upload')
.summary('Upload file')
.req('{file:s, type:s}') // In practice, use multipart/form-data
.res(200, '{id:s, url:s, size:i}')
.res(400, '{error:s, code:s}');TypeScript Support
Alt Swagger includes full TypeScript definitions:
import * as swagger from '@sleeksky/alt-swagger';
swagger.server('https://api.example.com');
swagger.get('/users').res(200, '[{id:number, name:string}]');
const spec: swagger.SwaggerDoc = swagger.swaggerDoc('API');Integration with Frameworks
Fastify
const fastify = require('fastify')();
const swagger = require('@sleeksky/alt-swagger');
// Define spec
swagger.server('http://localhost:3000');
swagger.get('/users').res(200, '[{id:i, name:s}]');
// Register Swagger
fastify.register(require('@fastify/swagger'), {
specification: {
document: swagger.swaggerDoc('Fastify API')
}
});Hapi
const Hapi = require('@hapi/hapi');
const swagger = require('@sleeksky/alt-swagger');
const server = Hapi.server({ port: 3000 });
// Define spec
swagger.server('http://localhost:3000');
swagger.get('/users').res(200, '[{id:i, name:s}]');
// Use hapi-swagger
server.register([
require('hapi-swagger'),
{
options: {
documentationPage: true,
swaggerOptions: {
spec: swagger.swaggerDoc('Hapi API')
}
}
}
]);Best Practices
- Define schemas first: Use
swagger.ref.schema()for reusable schemas - Use meaningful tags: Group related endpoints with tags
- Document thoroughly: Always include summaries and descriptions
- Handle errors: Define error responses for all endpoints
- Version your API: Use semantic versioning in
swaggerDoc() - Validate schemas: Test your generated specs with OpenAPI validators
Contributing
Contributions are welcome! Please feel free to submit issues and pull requests.
License
MIT © SleekSky
