A comprehensive example demonstrating OpenAPI 3.1.0 specification generation with Swagger UI in Forge.
This example showcases:
- OpenAPI 3.1.0 Specification Generation: Automatic generation of OpenAPI spec from route definitions
- Swagger UI Integration: Interactive API documentation interface
- Route Metadata: Tags, summaries, descriptions, and operation IDs
- Security Schemes: JWT Bearer and API Key authentication
- Multiple Server Configurations: Development and production server URLs
- Route Grouping: Logical organization of API endpoints
- RESTful API Design: Complete CRUD operations for user management
- External Documentation Links: References to additional documentation
- Contact & License Information: API metadata and legal information
- How to configure OpenAPI generation in Forge
- How to add metadata to routes (tags, summaries, descriptions)
- How to define security schemes (JWT, API Key)
- How to organize routes with groups
- How to access the generated OpenAPI spec and Swagger UI
- Best practices for API documentation
cd v2/examples/openapi-demo
go run main.goThe server will start on http://localhost:8080
Open your browser and navigate to:
http://localhost:8080/api/v1/swagger
This provides an interactive interface where you can:
- Browse all available endpoints
- View request/response schemas
- Try out API calls directly from the browser
- See authentication requirements
Get the raw OpenAPI specification:
http://localhost:8080/api/v1/openapi.json
This returns the complete OpenAPI 3.1.0 specification in JSON format, which can be:
- Imported into API testing tools (Postman, Insomnia)
- Used for client code generation
- Validated against OpenAPI standards
- Shared with API consumers
GET /api/v1/users- List all usersGET /api/v1/users/:id- Get user by IDPOST /api/v1/users- Create new userPUT /api/v1/users/:id- Update userDELETE /api/v1/users/:id- Delete userGET /api/v1/users/search- Search users
GET /api/v1/admin/stats- Get system statisticsPOST /api/v1/admin/maintenance- Toggle maintenance mode
GET /api/v1/health- Health check
curl http://localhost:8080/api/v1/userscurl http://localhost:8080/api/v1/users/1curl -X POST http://localhost:8080/api/v1/users \
-H "Content-Type: application/json" \
-d '{
"username": "alice",
"email": "alice@example.com",
"password": "secret123",
"role": "user",
"tags": ["new", "premium"]
}'curl -X PUT http://localhost:8080/api/v1/users/1 \
-H "Content-Type: application/json" \
-d '{
"username": "johndoe_updated",
"role": "admin"
}'curl -X DELETE http://localhost:8080/api/v1/users/2# Search by query
curl "http://localhost:8080/api/v1/users/search?q=johndoe"
# Search by role
curl "http://localhost:8080/api/v1/users/search?role=admin"curl http://localhost:8080/api/v1/health# Get statistics
curl http://localhost:8080/api/v1/admin/stats
# Toggle maintenance mode
curl -X POST http://localhost:8080/api/v1/admin/maintenance \
-H "Content-Type: application/json" \
-d '{"enabled": true, "message": "System maintenance"}'The example uses forge.WithOpenAPI() to configure OpenAPI generation:
forge.WithOpenAPI(forge.OpenAPIConfig{
Title: "User Management API",
Description: "A comprehensive REST API for user management",
Version: "1.0.0",
// Server URLs
Servers: []forge.OpenAPIServer{
{
URL: "http://localhost:8080",
Description: "Development server",
},
},
// Security schemes
Security: map[string]forge.SecurityScheme{
"bearerAuth": {
Type: "http",
Scheme: "bearer",
BearerFormat: "JWT",
},
},
// UI settings
UIPath: "/swagger",
SpecPath: "/openapi.json",
UIEnabled: true,
SpecEnabled: true,
PrettyJSON: true,
})Each route can be annotated with metadata:
router.GET("/users/:id",
getUserHandler,
forge.WithSummary("Get user by ID"),
forge.WithDescription("Retrieve detailed information about a specific user"),
forge.WithTags("users"),
forge.WithOperationID("getUser"),
)Organize related routes with groups:
adminGroup := router.Group("/admin",
forge.WithGroupTags("admin"),
forge.WithGroupMetadata("requiresAuth", true),
)
adminGroup.GET("/stats", statsHandler,
forge.WithSummary("Get system statistics"),
)- API title, description, and version
- Contact information
- License details
- External documentation links
- Multiple server URLs (dev, production)
- Server descriptions
- JWT Bearer authentication
- API Key authentication
- Scheme descriptions
- Summaries and descriptions
- Tags for grouping
- Operation IDs for unique identification
- Deprecated flag support
- Logical grouping of operations
- Tag descriptions
- External documentation per tag
- All HTTP methods (GET, POST, PUT, DELETE)
- Path parameters
- Query parameters
- Request/response schemas
- Comprehensive Descriptions: Always provide clear summaries and descriptions
- Consistent Tagging: Use tags to logically group related operations
- Operation IDs: Provide unique, descriptive operation IDs
- Security Documentation: Clearly document authentication requirements
- Examples: Include request/response examples when possible
- Versioning: Version your API and document changes
- Server URLs: Provide accurate server URLs for each environment
- Add request/response schema validation
- Implement security middleware to enforce authentication
- Add more detailed parameter descriptions
- Include request/response examples
- Add error response documentation
- Implement rate limiting documentation
- Add webhook documentation
The example demonstrates a production-ready approach to API documentation:
- Separation of Concerns: Handlers are separate from routing configuration
- In-Memory Storage: Simple user store for demo purposes (use database in production)
- Error Handling: Consistent error response format
- RESTful Design: Follows REST conventions for resource management
- Documentation First: API design is documented as it's built
- Ensure
UIEnabled: truein config - Check that the server is running on the correct port
- Verify the UI path matches your configuration
- Ensure routes are registered before app starts
- Check that
SpecEnabled: truein config - Verify route metadata is properly set
- Add CORS middleware if accessing from different origin
- Configure allowed origins and headers
This example is part of the Forge framework and is available under the same license as the main project.