SwagDoc

SwagDoc automatically generates Swagger/OpenAPI documentation from your API traffic without requiring any code changes.
Features
- Acts as a reverse proxy to capture API traffic
- Analyzes HTTP requests and responses to infer API structure
- Automatically detects data types, parameters, and response schemas
- Path parameter detection and templating (numeric IDs, UUIDs)
- Authentication flow detection (Bearer, API keys)
- Schema merging across multiple observations
- Generates OpenAPI 3.0 documentation based on observed traffic
- No code changes required to your existing API
- Graceful shutdown with signal handling
Installation
Using Go
go install github.com/parnexcodes/swag-doc/cmd/swagdoc@latest
From Releases
Download pre-built binaries from the Releases page. Binaries are available for Linux, macOS, and Windows (amd64/arm64).
From Source
git clone https://github.com/parnexcodes/swag-doc.git
cd swag-doc
make build
Usage
As a Proxy
Start SwagDoc as a proxy in front of your API:
swagdoc proxy --port 8080 --target http://your-api-server.com
This starts a proxy server that forwards requests to your API server and captures traffic for documentation. Press Ctrl+C to stop gracefully.
Generating Documentation
Once you have captured API traffic, generate OpenAPI documentation:
swagdoc generate --output swagger.json
CLI Reference
Proxy Command
| Flag |
Description |
Default |
--port |
Port to run the proxy server on |
8080 |
--target |
Target API server URL (required) |
|
--data-dir |
Directory to store API transaction data |
./swagdoc-data |
--max-body-bytes |
Maximum response body size (in bytes) captured per transaction; the full response is still forwarded to the client |
10485760 (10 MiB) |
--max-ws-message-bytes |
Maximum WebSocket message payload size (in bytes) captured per message; the full payload is still forwarded |
65536 (64 KiB) |
--max-ws-messages |
Maximum WebSocket messages captured per connection; forwarding continues after the limit |
1000 |
Generate Command
| Flag |
Description |
Default |
--output |
Output file for documentation; .yaml/.yml paths produce YAML, all others produce JSON |
swagger.json |
--data-dir |
Directory to read transaction data from |
./swagdoc-data |
--title |
Title for the API documentation |
API Documentation |
--description |
Description for the API documentation |
Generated API documentation |
--version |
API version |
1.0.0 |
--base-path |
Base path for the API |
http://localhost:8080 |
--cleanup |
Delete the data directory after generating |
false |
--group-by-path |
Group API endpoints by path segments |
true |
--tag-mapping |
Custom tag mappings in format path:tag |
|
--version-prefix |
Custom version prefixes |
|
--format |
Documentation format to generate: openapi, asyncapi, or graphql |
openapi |
Version Command
swagdoc version
# swagdoc dev (commit: none, built: unknown)
WebSocket API Documentation
SwagDoc also documents WebSocket endpoints as a standard AsyncAPI 3.1.0 document, generated from the same captured traffic:
swagdoc generate --format asyncapi --output asyncapi.json
- The proxy captures WebSocket handshakes (path, headers, subprotocol) and the messages exchanged in each direction, forwarding the live connection untouched.
- Each templated endpoint (numeric IDs and UUIDs become
{param} segments) becomes an AsyncAPI channel with the path as its address; client messages appear as a receive operation and server messages as a send operation, with payload schemas inferred from JSON payloads.
- Authentication observed in handshakes (Bearer tokens, API keys) is emitted as AsyncAPI security schemes on the affected operations.
- YAML output works the same as for OpenAPI: a
.yaml/.yml output path produces YAML.
Captured WebSocket sessions are stored in ws-session-*.json files, separate from HTTP session-*.json files; OpenAPI generation ignores them, so swagger.json output is unaffected by WebSocket traffic. Compressed (permessage-deflate) payloads are captured as-is and documented as binary.
GraphQL API Documentation
SwagDoc can infer a GraphQL schema from captured HTTP requests and emit standard GraphQL SDL:
swagdoc generate --format graphql --output schema.graphql
- GraphQL requests are detected from
application/graphql bodies, JSON bodies with a parseable query field, and URL-encoded query fields. Queries, mutations, subscriptions, variables, aliases, fragments, response object types, lists, and scalar fields are merged across observations.
- The output contains
Query, Mutation, and Subscription root fields, named object types, input types inferred from variables, and conservative nullable response fields. It contains type structure only; captured values are never emitted.
- SDL output is plain text regardless of the output filename extension.
.graphql or .gql is recommended.
- GraphQL-over-GET requests are not detected because query parameters are sanitized during capture. GraphQL-over-WebSocket subscription messages remain part of the AsyncAPI workflow rather than this SDL generator.
Organizing API Documentation
SwagDoc automatically organizes endpoints into logical groups based on URL path structure:
/auth/login and /auth/register → "Auth" tag
/users/123 and /users/profile → "Users" tag
/api/v1/orders → "Orders" tag (handles version prefixes)
Customize grouping:
swagdoc generate \
--tag-mapping "auth:Authentication" \
--tag-mapping "users:User Management" \
--version-prefix "api" \
--version-prefix "v4"
How It Works
- Capture: SwagDoc acts as a reverse proxy, intercepting all HTTP requests and responses.
- Store: Raw transaction data is stored on disk. Sensitive headers and query parameters are redacted. Response bodies larger than
--max-body-bytes are truncated for capture (the client still receives the full response), and transactions are flushed to disk periodically rather than on every request.
- Analyze: Path patterns, authentication schemes, and data types are detected from the captured traffic.
- Generate: An OpenAPI 3.0 specification is generated from the analyzed data, with schema merging across multiple observations.
Development
Building
make build # Build binary
make test # Run tests with race detector
make lint # Run golangci-lint
make fmt # Format code
make coverage # Generate coverage report
make vulncheck # Run vulnerability scanner
make clean # Clean artifacts
CI/CD
The project uses GitHub Actions:
- CI (
ci.yml): Runs on every push/PR to master — lint, vulnerability check, tests (Linux/macOS/Windows), build
- Release (
release.yml): Runs on version tags (v*) — cross-compiles via GoReleaser, creates GitHub release with checksums
To create a release:
git tag v1.0.0
git push origin v1.0.0
Demo
make demo
This starts the example API, proxies to it, sends sample HTTP, GraphQL, and WebSocket messages, generates swagger.json, asyncapi.json, and schema.graphql, and stops the servers.
Future Features
- Framework-specific middleware (Express, Gin, FastAPI, etc.)
- Interactive UI for viewing and editing generated docs
- gRPC support
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT