APISpec analyzes your Go code and automatically generates an OpenAPI 3.1 spec (YAML or JSON). It detects routes for popular frameworks (Gin, Echo, Chi, Fiber, net/http), follows call graphs to the final handlers, and infers request/response types from real code (struct tags, literals, generics, and more).
TL;DR: Point APISpec at your module. Get an OpenAPI spec and, optionally, an interactive call-graph diagram.
Click the image above to watch the full demo on YouTube
- Automated OpenAPI: Generate OpenAPI 3.1 from real Go code.
- Framework-aware: Detects Gin, Echo, Chi, Fiber, and net/http automatically.
- Accurate by analysis: Builds a call graph to resolve handlers, parameters, bodies, and responses.
- Configurable: YAML config plus CLI flags; flags always win.
- Visualize: Optional HTML call-graph diagram for debugging.
- Extensible: Pattern-based framework config; add new frameworks without changing core logic.
- Smart Type Resolution: Automatically resolves underlying primitive types for aliases and enums.
- Array Type Support: Comprehensive handling of Go arrays including fixed-size arrays (
[16]byte) and variable-length arrays ([...]int). - External Type Resolution: Automatically resolves external package types to their underlying primitives while preserving internal project types.
- Validator Tag Support: Comprehensive support for go-playground/validator tags with automatic OpenAPI constraint mapping.
- Function Literal Analysis: Full support for anonymous functions in route handlers.
- Comprehensive Error Handling: Robust handling of edge cases and invalid inputs.
- Performance Profiling: Built-in CPU, memory, block, mutex, and trace profiling for performance analysis.
- Configurable Limits: Fine-tune analysis limits for large codebases with detailed warning messages.
- CGO Support: Skip CGO packages during analysis to avoid build errors.
Note: Generating call-graph diagrams and metadata files consumes additional resources and time.
- Route registration: Detects
HandleFuncandHandlecalls with path and handler arguments - Handler function detection: Identifies handler functions passed as arguments to route registration
- HTTP method extraction: Automatically extracts HTTP methods from handler function names or explicit method calls
- Path parameter detection: Recognizes path parameters in route patterns (e.g.,
/users/{id}) - Subrouter support: Handles nested routing with
PathPrefixandSubrouter - Parameter extraction: Path parameters are not yet fully resolved to handler function parameters
- Conditional routing: Dynamic route registration based on runtime conditions is not supported
- Gin: Full support for route registration, and parameter handling
- Chi: Full support for route mounting, grouping, parameter extraction, and render package integration
- Echo: Full support for route registration, grouping, and parameter handling
- Fiber: Full support for route registration, grouping, and parameter handling
- Standard net/http: Basic support for
HandleFuncandHandlecalls
APISpec focuses on practical coverage for real-world services. Current coverage includes:
- Alias imports: supports import aliases in analysis.
- Alias types: type aliases are detected and resolved to underlying primitive types.
- Enum resolution: automatically resolves enum types to their underlying primitive types (string, int, etc.) from constants, enum tags, or oneof validator tags.
- Assignment and alias tracking: short
:=,=, multi-assign, tuple returns, latest-wins resolution, alias chains, and shadowing. - Conditional methods: detecting HTTP methods set via switch/if around net/http
Handle/HandleFuncis not supported. - Composite literals / maps / slices / arrays: recognizes literal and container types for schema mapping.
- Array type support: comprehensive handling of fixed-size arrays (
[16]byte,[5]int) and variable-length arrays ([...]int). - Dependency injection: supports route grouping mounted via dependency injection.
- Duplicate status codes: paths with the same status code and different schemas are not yet supported.
- External type introspection: types from external packages are automatically resolved to their underlying primitives; complex external types can be defined via
externalTypesin config. - Generics (functions): detects type parameters and maps concrete types at call sites.
- Generics (types): generic struct and type instantiation are partially supported.
- Inferred status codes: status codes assigned via variables are not inferred.
- Interfaces: captures interface types and methods; unresolved dynamic values are represented generically.
- Chain calls: efficiently processes method chaining and establishes parent-child relationships in the call graph.
- Nested calls: handles chained/method calls and nested expressions.
- Parameter tracing across calls: follows arguments across the call graph; maps function parameters to call arguments.
- Interface param resolution: interface type parameters in functions are not yet fully resolved to concrete types.
- Parent object type tracing: limited ability to trace the receiver/parent type;
Decodeon non-body targets may be misclassified. - Pointers and dereference: detects
*Tand automatically dereferences when configured. - Selectors and field access: resolves
pkg.Type.Fieldand nested selectors where possible. - Struct fields: reads field types, embedded fields, and struct tags (
json,xml,form, etc.). - Nested struct types: supports anonymous nested structs within struct fields, preserving complete type information for accurate schema generation.
- Function and method return types: automatically resolves and captures return types from function signatures, enabling accurate type resolution in pattern matchers.
- CGO support: includes a flag to skip CGO packages during analysis, useful for projects with complex C dependencies.
- Function literals: supports anonymous functions (func literals) in route handlers and call analysis.
- Validator tag support: comprehensive support for go-playground/validator tags including validation rules, constraints, and enum definitions.
APISpec automatically resolves underlying types for aliases and enums:
// Enum types are resolved to their underlying primitive type
type AllowedUserType string
const (
UserTypeAdmin AllowedUserType = "admin"
UserTypeCustomer AllowedUserType = "user"
)
// In your struct, AllowedUserTypes will be resolved to []string
type Permission struct {
ID string
Resource string
Operation string
AllowedUserTypes []domain.AllowedUserType // Resolves to []string
}
// Generated OpenAPI schema:
// AllowedUserTypes:
// type: array
// items:
// type: string// Pointer aliases are also resolved
type UserID *int64
type User struct {
ID UserID // Resolves to integer
}
// Generated OpenAPI schema:
// ID:
// type: integer
// format: int64APISpec provides comprehensive support for Go arrays, including fixed-size arrays and variable-length arrays:
// Fixed-size byte arrays are converted to string with maxLength
type User struct {
ID [16]byte // Converts to string with format: "byte", maxLength: 16
Token [32]byte // Converts to string with format: "byte", maxLength: 32
Scores [5]int // Converts to array with maxItems: 5, minItems: 5
Tags [10]string // Converts to array with maxItems: 10, minItems: 10
}
// Variable-length arrays
type Config struct {
Values [...]int // Converts to array without size constraints
}User:
type: object
properties:
ID:
type: string
format: byte
maxLength: 16
Token:
type: string
format: byte
maxLength: 32
Scores:
type: array
items:
type: integer
maxItems: 5
minItems: 5
Tags:
type: array
items:
type: string
maxItems: 10
minItems: 10
Config:
type: object
properties:
Values:
type: array
items:
type: integerAPISpec intelligently handles external package types by resolving them to their underlying primitives while preserving internal project types:
// External types (from other packages) are resolved to primitives
import (
"github.com/google/uuid"
"github.com/your-org/shared"
)
type User struct {
ID uuid.UUID // Resolves to string with format: "uuid"
External shared.ExternalType // Resolves to underlying primitive
Internal models.User // Kept as-is (internal project type)
}- External Types: Types from packages like
github.com/google/uuid.UUIDare automatically resolved to their underlying primitive types (e.g.,stringwithformat: "byte") - Internal Types: Types from your own project (even in different packages) are preserved as-is for proper schema generation
- Standard Library: Types like
time.Timeare handled appropriately based on configuration
User:
type: object
properties:
ID:
type: string
format: byte
maxLength: 16
External:
type: string # Resolved from external package
Internal:
$ref: '#/components/schemas/User' # Internal type preservedAPISpec provides comprehensive support for go-playground/validator tags, automatically converting validation rules to OpenAPI schema constraints:
// Status represents different status values
type Status string
// Status constants
const (
StatusActive Status = "active"
StatusInactive Status = "inactive"
StatusPending Status = "pending"
)
type User struct {
ID int `json:"id" validate:"required,min=1"`
Name string `json:"name" validate:"required,min=2,max=50"`
Email string `json:"email" validate:"required,email"`
Age int `json:"age" validate:"min=18,max=120"`
Status Status `json:"status"`
MaritalStatus string `json:"marital_status" validate:"required,oneof=single married divorced"`
Bio string `json:"bio" min:"10" max:"500"`
Website string `json:"website" pattern:"^https?://.*"`
Country string `json:"country" enum:"US,CA,UK,DE,FR"`
}User:
type: object
properties:
age:
type: integer
minimum: 18
maximum: 120
bio:
type: string
country:
type: string
enum:
- US
- CA
- UK
- DE
- FR
email:
type: string
format: email
id:
type: integer
minimum: 1
marital_status:
type: string
enum:
- single
- married
- divorced
name:
type: string
status:
type: string
enum:
- active
- inactive
- pending
website:
type: string
required:
- id
- name
- email
- marital_statusAPISpec supports most go-playground/validator tags:
Note: Some advanced validator tags like
dive(for array element validation) are not yet supported but are planned for future releases.
| Validator Tag | OpenAPI Mapping | Description |
|---|---|---|
required |
required: true |
Field is required |
omitempty |
required: false |
Field is optional |
min=N |
minimum: N |
Minimum value/length |
max=N |
maximum: N |
Maximum value/length |
len=N |
minLength: N, maxLength: N |
Exact length |
email |
format: email |
Email format validation |
url |
format: uri |
URL format validation |
uuid |
format: uuid |
UUID format validation |
oneof=val1 val2 |
enum: [val1, val2] |
Enum values |
alphanum |
pattern: "^[a-zA-Z0-9]+$" |
Alphanumeric characters |
alpha |
pattern: "^[a-zA-Z]+$" |
Alphabetic characters |
numeric |
pattern: "^[0-9]+$" |
Numeric characters |
containsany=chars |
pattern: ".*[chars].*" |
Must contain any of the characters |
e164 |
pattern: "^\\+[1-9]\\d{1,14}$" |
E.164 phone number format |
dive |
❌ Not yet supported | Array element validation |
APISpec now supports anonymous functions in route handlers:
// Gin example with function literals
router.POST("/users", func(c *gin.Context) {
var user CreateUserRequest
if err := c.ShouldBindJSON(&user); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
// ... handler logic
c.JSON(201, user)
})
// Echo example with function literals
e.POST("/products", func(c echo.Context) error {
var product Product
if err := c.Bind(&product); err != nil {
return c.JSON(400, map[string]string{"error": err.Error()})
}
// ... handler logic
return c.JSON(201, product)
})These function literals are properly analyzed and their request/response types are extracted for OpenAPI generation.
graph TD
A[Go Source Code] --> B[Package Analysis & Type Checking]
B --> C[Framework Detection]
C --> D[Metadata Generation]
D --> E[Call Graph Construction]
E --> F[Tracker Tree with Limits]
G[Config File<br/>--config] -.-> H[Pattern Extraction]
F --> H
D --> H
H --> I[OpenAPI Spec Generation]
I --> J{{Output Format?}}
J -->|JSON| K[openapi.json]
J -->|YAML| L[openapi.yaml]
E -.-> M[Call Graph Diagram<br/>--diagram]
M -.-> N[diagram.html]
H -.-> O[Effective Config Output<br/>--output-config]
O -.-> P[apispec-config.yaml]
D -.-> Q[Metadata Output<br/>--write-metadata]
Q -.-> R[metadata.yaml]
APISpec executes a multi-stage process to analyze your code and generate the OpenAPI specification. The workflow is designed to be robust and flexible, handling complex Go projects with ease.
-
Initialization & Flag Parsing: The tool starts, prints license information, and parses all command-line flags provided by the user.
-
Module Discovery: It finds the root of the Go module by searching for the
go.modfile and changes the working directory to the module root. -
Package Loading & Type-Checking: APISpec loads and performs a full type-check on all Go packages within the module (
./...), building a rich understanding of the code's types and syntax. -
Framework Detection: It analyzes the project's dependencies to automatically detect the web framework being used (e.g., Gin, Chi, Echo, Fiber, or standard
net/http). -
Configuration Loading: The tool loads a framework-specific default configuration. If a custom
--configfile is provided, it loads that instead. CLI flags always override settings from any configuration file. -
Metadata Generation: It traverses the Abstract Syntax Trees (AST) of the parsed packages to generate a detailed
metadataobject. This object contains information about packages, function calls, and string constants. -
Call Graph Construction: Using the generated metadata, APISpec constructs a call graph tree. This tree traces the flow of execution from router definitions to the final handler functions, respecting limits set by flags like
--max-nodesto prevent infinite recursion. -
OpenAPI Mapping: The call graph and metadata are processed by a framework-specific mapper. This mapper identifies API routes, parameters, request bodies, and responses, translating them into the OpenAPI specification structure.
-
Specification Generation: The final OpenAPI object is marshaled into either YAML or JSON format, based on the output file extension (
.yaml, or.json). -
File Output: The resulting specification file is written to the path specified by the
--outputflag. If requested, an interactive HTML call graph diagram is also generated.
📖 For detailed installation instructions, see INSTALLATION.md
go install github.com/ehabterra/apispec/cmd/apispec@latest# Clone the repository
git clone https://github.com/ehabterra/apispec.git
cd apispec
# Build and install
make install-local # Install to ~/go/bin (no sudo required)
# OR
make install # Install to /usr/local/bin (requires sudo)# Download and run the installation script
curl -sSL https://raw.githubusercontent.com/ehabterra/apispec/main/scripts/install.sh | bash -s go-installNote: Make sure your Go bin directory is in your PATH. Add this to your shell profile:
export PATH=$HOME/go/bin:$PATH# Clone the repository
git clone https://github.com/ehabterra/apispec.git
cd apispec
# Build the binary
make build
# Or build directly with Go
go build -o apispec ./cmd/apispec
# Build the API diagram server
go build -o apidiag ./cmd/apidiag# Generate OpenAPI spec from your Go project
./apispec --output openapi.yaml
# Generate with custom config
./apispec --config my-config.yaml --output openapi.yaml
# Generate with call graph diagram
./apispec --output openapi.yaml --diagram diagram.html
# Generate metadata for debugging
./apispec --output openapi.yaml --write-metadata
# Performance profiling for large codebases
./apispec --output openapi.yaml --cpu-profile --mem-profile
# Skip CGO packages to avoid build errors
./apispec --output openapi.yaml --skip-cgo
# Fine-tune analysis limits for large projects
./apispec --output openapi.yaml --max-nodes 100000 --max-children 1000 --max-recursion-depth 15APISpec includes a web-based API diagram server (apidiag) that provides an interactive interface for exploring call graphs. This is particularly useful for large codebases where static diagrams become unwieldy.
# Start the API diagram server
./apidiag
# Or if installed globally
apidiag
# Open your browser to http://localhost:8080- Interactive Web Interface: Browse call graphs through a modern web UI
- Paginated Visualization: Handle large codebases with efficient pagination
- Advanced Filtering: Filter by packages, functions, files, receivers, signatures, and more
- Real-time Analysis: Live analysis of your Go project structure
- Export Capabilities: Export diagrams in multiple formats (SVG, PNG, PDF, JSON)
- RESTful API: Programmatic access to diagram data
# Start server on custom port
./apidiag --port 9090
# Analyze specific directory
./apidiag --dir ./my-go-project
# Custom page size and depth
./apidiag --page-size 50 --max-depth 2
# Show version information
./apidiag --version📖 For detailed documentation, see cmd/apidiag/README.md
import (
"os"
"github.com/ehabterra/apispec/generator"
"github.com/ehabterra/apispec/spec"
"gopkg.in/yaml.v3"
)
func main() {
cfg := spec.DefaultGinConfig() // or spec.LoadAPISpecConfig("apispec.yaml")
gen := generator.NewGenerator(cfg)
openapi, err := gen.GenerateFromDirectory("./your-project")
if err != nil { panic(err) }
data, _ := yaml.Marshal(openapi)
os.WriteFile("openapi.yaml", data, 0644)
}| Full Flag | Shorthand | Description | Default |
|---|---|---|---|
--output |
-o |
Output file for OpenAPI spec | openapi.json |
--dir |
-d |
Directory to parse for Go files | . (current dir) |
--title |
-t |
Title of the API | Generated API |
--api-version |
-v |
Version of the API | 1.0.0 |
--description |
-D |
API description | "" |
--terms-url |
-T |
Terms of Service URL | "" |
--contact-name |
-N |
Contact person/organization name | Ehab |
--contact-url |
-U |
Contact URL | https://ehabterra.github.io/ |
--contact-email |
-E |
Contact email | ehabterra@hotmail.com |
--license-name |
-L |
License name | "" |
--license-url |
-lu |
License URL | "" |
--openapi-version |
-O |
OpenAPI spec version | 3.1.1 |
--config |
-c |
Path to custom config YAML | "" |
--output-config |
-oc |
Output effective config to YAML | "" |
--write-metadata |
-w |
Write metadata.yaml to disk | false |
--split-metadata |
-s |
Split metadata into separate files | false |
--diagram |
-g |
Save call graph as HTML | "" |
--max-nodes |
-mn |
Max nodes in call graph tree | 50000 |
--max-children |
-mc |
Max children per node | 500 |
--max-args |
-ma |
Max arguments per function | 100 |
--max-depth |
-md |
Max depth for nested arguments | 100 |
--max-recursion-depth |
-mrd |
Max recursion depth to prevent infinite loops | 10 |
--skip-cgo |
Skip CGO packages during analysis | true |
|
--include-file |
Include files matching pattern (multiple) | "" |
|
--include-package |
Include packages matching pattern (multiple) | "" |
|
--include-function |
Include functions matching pattern (multiple) | "" |
|
--include-type |
Include types matching pattern (multiple) | "" |
|
--exclude-file |
Exclude files matching pattern (multiple) | "" |
|
--exclude-package |
Exclude packages matching pattern (multiple) | "" |
|
--exclude-function |
Exclude functions matching pattern (multiple) | "" |
|
--exclude-type |
Exclude types matching pattern (multiple) | "" |
|
--cpu-profile |
Enable CPU profiling | false |
|
--mem-profile |
Enable memory profiling | false |
|
--block-profile |
Enable block profiling | false |
|
--mutex-profile |
Enable mutex profiling | false |
|
--trace-profile |
Enable trace profiling | false |
|
--custom-metrics |
Enable custom metrics collection | false |
|
--profile-dir |
Directory for profiling output files | profiles |
openapi: 3.1.0
info:
title: User Management API
version: 1.0.0
description: API for managing users and permissions
paths:
/users:
get:
summary: List users
parameters:
- name: page
in: query
schema:
type: integer
minimum: 1
default: 1
- name: limit
in: query
schema:
type: integer
minimum: 1
maximum: 100
default: 20
responses:
'200':
description: List of users
content:
application/json:
schema:
type: object
properties:
users:
type: array
items:
$ref: '#/components/schemas/User'
pagination:
$ref: '#/components/schemas/Pagination'
post:
summary: Create user
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateUserRequest'
responses:
'201':
description: User created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'400':
description: Invalid request data
/users/{id}:
get:
summary: Get user by ID
parameters:
- name: id
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: User details
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'404':
description: User not found
components:
schemas:
User:
type: object
properties:
id:
type: string
format: uuid
name:
type: string
email:
type: string
format: email
status:
type: string
enum: ["active", "inactive", "pending"]
createdAt:
type: string
format: date-time
permissions:
type: array
items:
type: string
enum: ["admin", "user", "driver", "store_manager", "picker"]
required: ["id", "name", "email"]
CreateUserRequest:
type: object
properties:
name:
type: string
email:
type: string
format: email
permissions:
type: array
items:
type: string
required: ["name", "email"]
Pagination:
type: object
properties:
page:
type: integer
minimum: 1
limit:
type: integer
minimum: 1
total:
type: integer
totalPages:
type: integerAPISpec uses YAML configuration files to define framework patterns and behavior. Here are examples for different frameworks:
# Example Gin configuration (apispec.yaml)
info:
title: My API
version: 1.0.0
description: A comprehensive API for user management
framework:
routePatterns:
- callRegex: ^(?i)(GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD)$
recvTypeRegex: ^github\.com/gin-gonic/gin\.\*(Engine|RouterGroup)$
handlerArgIndex: 1
methodFromCall: true
pathFromArg: true
handlerFromArg: true
requestBodyPatterns:
- callRegex: ^(?i)(BindJSON|ShouldBindJSON|BindXML|BindYAML|BindForm|ShouldBind)$
typeFromArg: true
deref: true
- callRegex: ^Decode$
typeFromArg: true
deref: true
- callRegex: ^Unmarshal$
typeArgIndex: 1
typeFromArg: true
deref: true
responsePatterns:
- callRegex: ^(?i)(JSON|String|XML|YAML|ProtoBuf|Data|File|Redirect)$
typeArgIndex: 1
statusFromArg: true
typeFromArg: true
- callRegex: ^Marshal$
typeFromArg: true
deref: true
- callRegex: ^Encode$
typeFromArg: true
deref: true
paramPatterns:
- callRegex: ^Param$
paramIn: path
- callRegex: ^Query$
paramIn: query
- callRegex: ^DefaultQuery$
paramIn: query
- callRegex: ^GetHeader$
paramIn: header
mountPatterns:
- callRegex: ^Group$
recvTypeRegex: ^github\.com/gin-gonic/gin\.\*(Engine|RouterGroup)$
routerArgIndex: 1
pathFromArg: true
routerFromArg: true
isMount: true
# Type mappings for custom types and external packages
typeMapping:
- goType: time.Time
openapiType:
type: string
format: date-time
- goType: uuid.UUID
openapiType:
type: string
format: uuid
- goType: decimal.Decimal
openapiType:
type: string
format: decimal
# Validator tag support is automatically enabled
# APISpec will parse validate tags and convert them to OpenAPI constraints
# Example: validate:"required,email" -> required: true, format: email
# External types that can't be introspected automatically
# Note: APISpec automatically resolves external package types to their underlying primitives
# Only define complex external types that need custom schemas here
externalTypes:
- name: github.com/gin-gonic/gin.H
openapiType:
type: object
additionalProperties: true
- name: github.com/your-package/CustomResponse
openapiType:
type: object
properties:
success:
type: boolean
data:
type: object
message:
type: string# Example Echo configuration
framework:
routePatterns:
- callRegex: ^(?i)(GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD)$
recvTypeRegex: ^github\.com/labstack/echo\.\*(Echo|Group)$
handlerArgIndex: 1
methodFromCall: true
pathFromArg: true
handlerFromArg: true
requestBodyPatterns:
- callRegex: ^(?i)(Bind|BindJSON|BindXML|BindYAML)$
typeFromArg: true
deref: true
responsePatterns:
- callRegex: ^(?i)(JSON|String|XML|YAML|Blob|File|Stream)$
typeArgIndex: 1
statusFromArg: true
typeFromArg: true
paramPatterns:
- callRegex: ^Param$
paramIn: path
- callRegex: ^QueryParam$
paramIn: query
- callRegex: ^FormValue$
paramIn: formData# Handle custom domain types
typeMapping:
- goType: domain.UserStatus
openapiType:
type: string
enum: ["active", "inactive", "pending"]
- goType: domain.Priority
openapiType:
type: integer
enum: [1, 2, 3, 4, 5]
- goType: []domain.Tag
openapiType:
type: array
items:
type: string# Define schemas for external packages
externalTypes:
- name: github.com/your-org/shared.Response
openapiType:
type: object
properties:
code:
type: integer
message:
type: string
data:
type: object
additionalProperties: true
- name: github.com/your-org/shared.Pagination
openapiType:
type: object
properties:
page:
type: integer
minimum: 1
limit:
type: integer
minimum: 1
maximum: 100
total:
type: integer- Go 1.24+ (Didn't test it on version before 1.24)
- Understanding of AST (Abstract Syntax Tree)
- Familiarity with OpenAPI 3.1 specification
apispec/
├── cmd/
│ └── apispec/ # CLI entry point
│ └── main.go
├── generator/ # High-level generator interface
│ ├── generator.go
│ └── generator_test.go
├── internal/
│ ├── core/ # Framework detection and core logic
│ ├── engine/ # Processing engine
│ ├── metadata/ # Code analysis and metadata extraction
│ └── spec/ # OpenAPI spec generation and mapping
├── spec/ # Public spec package
├── testdata/ # Example projects for testing
├── scripts/ # Build and utility scripts
├── docs/ # Documentation files
└── .github/ # GitHub workflows and templates
# Run all tests
make test
# Run tests with coverage
make coverage
# Run comprehensive mapper tests
go test ./internal/spec -v -run "Test.*Comprehensive"
# Build the binary
make build
# Update coverage badge
make update-badgeAPISpec includes comprehensive test suites covering:
- Unit tests for all packages
- Integration tests for framework detection and OpenAPI generation
- Comprehensive mapper tests for edge cases and type resolution
- Framework-specific tests for Gin, Echo, Chi, and Fiber
Run specific test categories:
# Test mapper functionality
go test ./internal/spec -v
# Test metadata extraction
go test ./internal/metadata -v
# Test with coverage
go test ./... -cover- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Add tests for new functionality
- Run tests to ensure everything works (
make test) - Update coverage badge (
make update-badge) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Update the framework detection logic in
internal/core/detector.go - Add default configuration in
internal/spec/config.go - Update the framework detection logic in
cmd/apispec/main.go - Add test cases in
testdata/
- All code should have tests
- Aim to maintain or improve test coverage
- Follow Go coding standards
- Add documentation for new features
APISpec includes built-in profiling capabilities to help you analyze and optimize performance:
- CPU Profiling: Analyze function execution time and call frequency
- Memory Profiling: Track memory allocation patterns and identify leaks
- Block Profiling: Detect goroutine blocking issues
- Mutex Profiling: Identify mutex contention problems
- Trace Profiling: Detailed execution trace analysis
- Custom Metrics: Application-specific performance metrics
# Basic CPU profiling
./apispec -d ./my-project --cpu-profile
# Comprehensive profiling
./apispec -d ./my-project --cpu-profile --mem-profile --custom-metrics
# Custom profiling directory
./apispec -d ./my-project --cpu-profile --profile-dir ./analysis
# Analyze with Go tools
go tool pprof profiles/cpu.prof
go tool pprof profiles/mem.prof
go tool trace profiles/trace.outThe custom metrics collector automatically tracks:
- Memory usage patterns
- Goroutine counts
- Function execution times
- System resource utilization
Generated metrics are saved as JSON and can be analyzed for performance insights.
APISpec implements several safeguards to prevent excessive resource usage:
| Parameter | Default Value | Description |
|---|---|---|
| MaxNodesPerTree | 50,000 | Maximum nodes in call graph |
| MaxChildrenPerNode | 500 | Children per node |
| MaxArgsPerFunction | 100 | Arguments per function |
| MaxNestedArgsDepth | 100 | Argument nesting depth |
| MaxRecursionDepth | 10 | Maximum recursion depth to prevent infinite loops |
Warning Messages: APISpec now provides clear warnings when limits are reached:
Warning: MaxNodesPerTree limit (50000) reached, truncating tree at node example.com/pkg.Function
Warning: MaxChildrenPerNode limit (500) reached for node example.com/pkg.Function, truncating children
Warning: MaxRecursionDepth limit (10) reached for node example.com/pkg.FunctionAdjust these with CLI flags if needed for large codebases.
- docs/INSTALLATION.md: Detailed installation instructions
- docs/RELEASE_WORKFLOW.md: Automated release process with GitHub Actions
- docs/TRACKER_TREE_USAGE.md: Guide to using TrackerTree for call graph analysis
- docs/CYTOGRAPHE_README.md: Documentation for the call graph visualization feature
- cmd/apispec/README.md: Main CLI tool documentation
- cmd/apidiag/README.md: Interactive API diagram server documentation
- internal/metadata/README.md: Metadata package documentation
- internal/spec/README.md: Spec generation package documentation
Apache License 2.0 - See LICENSE for details.

