https://github.com/oaswrap/spec
A lightweight, framework-agnostic OpenAPI 3.x specification builder for Go.
https://github.com/oaswrap/spec
go golang oas openapi openapi-3 openapi-generator swagger
Last synced: about 2 months ago
JSON representation
A lightweight, framework-agnostic OpenAPI 3.x specification builder for Go.
- Host: GitHub
- URL: https://github.com/oaswrap/spec
- Owner: oaswrap
- License: mit
- Created: 2025-07-29T06:10:55.000Z (2 months ago)
- Default Branch: main
- Last Pushed: 2025-08-07T12:13:01.000Z (2 months ago)
- Last Synced: 2025-08-07T14:17:00.389Z (2 months ago)
- Topics: go, golang, oas, openapi, openapi-3, openapi-generator, swagger
- Language: Go
- Homepage: https://pkg.go.dev/github.com/oaswrap/spec
- Size: 349 KB
- Stars: 63
- Watchers: 2
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# oaswrap/spec
[](https://github.com/oaswrap/spec/actions/workflows/ci.yml)
[](https://codecov.io/gh/oaswrap/spec)
[](https://pkg.go.dev/github.com/oaswrap/spec)
[](https://goreportcard.com/report/github.com/oaswrap/spec)
[](https://github.com/oaswrap/spec/blob/main/go.mod)
[](LICENSE)A lightweight, framework-agnostic OpenAPI 3.x specification builder for Go that gives you complete control over your API documentation without vendor lock-in.
## Why oaswrap/spec?
- **🎯 Framework Agnostic** — Works with any Go web framework or as a standalone tool
- **⚡ Zero Dependencies** — Powered by [`swaggest/openapi-go`](https://github.com/swaggest/openapi-go) with minimal overhead
- **🔧 Programmatic Control** — Build specs in pure Go code with full type safety
- **🚀 Adapter Ecosystem** — Seamless integration with popular frameworks via dedicated adapters
- **📝 CI/CD Ready** — Generate specs at build time for documentation pipelines## Installation
```bash
go get github.com/oaswrap/spec
```## Quick Start
### Basic Usage (Standalone)
Perfect for generating OpenAPI specs in CI/CD, build scripts, or documentation tools:
```go
package mainimport (
"log""github.com/oaswrap/spec"
"github.com/oaswrap/spec/option"
)func main() {
// Create a new OpenAPI router
r := spec.NewRouter(
option.WithTitle("My API"),
option.WithVersion("1.0.0"),
option.WithServer("https://api.example.com"),
)// Add routes
v1 := r.Group("/api/v1")
v1.Post("/login",
option.Summary("User login"),
option.Request(new(LoginRequest)),
option.Response(200, new(LoginResponse)),
)v1.Get("/users/{id}",
option.Summary("Get user by ID"),
option.Request(new(GetUserRequest)),
option.Response(200, new(User)),
)// Generate OpenAPI spec
if err := r.WriteSchemaTo("openapi.yaml"); err != nil {
log.Fatal(err)
}log.Println("✅ OpenAPI spec generated at openapi.yaml")
}type LoginRequest struct {
Username string `json:"username" required:"true"`
Password string `json:"password" required:"true"`
}type LoginResponse struct {
Token string `json:"token"`
}type GetUserRequest struct {
ID string `path:"id" required:"true"`
}type User struct {
ID string `json:"id"`
Name string `json:"name"`
}
```📖 **[View the generated spec](https://rest.wiki/?https://raw.githubusercontent.com/oaswrap/spec/main/examples/basic/openapi.yaml)** on Rest.Wiki
### Framework Integration
For seamless HTTP server integration, use one of our framework adapters:
| Framework | Package |
|-----------|---------|
| **Chi** | [`chiopenapi`](/adapter/chiopenapi) |
| **Echo** | [`echoopenapi`](/adapter/echoopenapi) |
| **Gin** | [`ginopenapi`](/adapter/ginopenapi) |
| **Fiber** | [`fiberopenapi`](/adapter/fiberopenapi) |
| **HTTP** | [`httpopenapi`](/adapter/httpopenapi) |
| **Mux** | [`muxopenapi`](/adapter/muxopenapi) |Each adapter provides:
- ✅ Automatic spec generation from your routes
- 📚 Built-in Swagger UI documentation at `/docs`
- 📄 YAML spec endpoints at `/docs/openapi.yaml`
- 🔧 Inline OpenAPI options with route definitionsVisit the individual adapter repositories for framework-specific examples and detailed integration guides.
## When to Use What?
### ✅ Use `spec` standalone when you:
- Generate OpenAPI files at **build time**
- Integrate with **CI/CD pipelines**
- Build **custom documentation tools**
- Need **static spec generation**
- Want **framework independence**### ✅ Use framework adapters when you:
- Want **automatic spec generation** from routes
- Need **built-in documentation UI**
- Prefer **inline OpenAPI configuration**
- Want **live spec endpoints**## Configuration Options
The `option` package provides comprehensive OpenAPI configuration:
### Basic Information
```go
option.WithOpenAPIVersion("3.0.3") // Default: "3.0.3"
option.WithTitle("My API")
option.WithDescription("API description")
option.WithVersion("1.2.3")
option.WithContact(openapi.Contact{
Name: "Support Team",
URL: "https://support.example.com",
Email: "support@example.com",
})
option.WithLicense(openapi.License{
Name: "MIT License",
URL: "https://opensource.org/licenses/MIT",
})
option.WithExternalDocs("https://docs.example.com", "API Documentation")
option.WithTags(
openapi.Tag{
Name: "User Management",
Description: "Operations related to user management",
},
openapi.Tag{
Name: "Authentication",
Description: "Authentication related operations",
},
)
```### Servers
```go
option.WithServer("https://api.example.com")
option.WithServer("https://api-example.com/{version}",
option.ServerDescription("Production Server"),
option.ServerVariables(map[string]openapi.ServerVariable{
"version": {
Default: "v1",
Enum: []string{"v1", "v2"},
Description: "API version",
},
}),
)
```### Security Schemes
```go
// Bearer token
option.WithSecurity("bearerAuth", option.SecurityHTTPBearer("Bearer"))// API Key
option.WithSecurity("apiKey", option.SecurityAPIKey("X-API-Key", "header"))// OAuth2
option.WithSecurity("oauth2", option.SecurityOAuth2(
openapi.OAuthFlows{
Implicit: &openapi.OAuthFlowsImplicit{
AuthorizationURL: "https://auth.example.com/authorize",
Scopes: map[string]string{
"read": "Read access",
"write": "Write access",
},
},
},
))
```### Route Documentation
```go
option.OperationID("getUserByID") // Unique operation ID
option.Summary("Short description") // Brief summary
option.Description("Detailed description") // Full description
option.Tags("User Management", "Authentication") // Group by tags
option.Request(new(RequestModel)) // Request body model
option.Response(200, new(ResponseModel), // Response model
option.ContentDescription("Successful response"),
option.ContentType("application/json"),
option.ContentDefault(true),
)
option.Security("bearerAuth") // Apply security scheme
option.Deprecated() // Mark as deprecated
option.Hidden() // Hide from spec
```### Parameter Definition
Define parameters using struct tags in your request models:```go
type GetUserRequest struct {
ID string `path:"id" required:"true" description:"User identifier"`
Limit int `query:"limit" description:"Maximum number of results"`
APIKey string `header:"X-API-Key" description:"API authentication key"`
}
```### Group-Level Configuration
Apply settings to all routes within a group:```go
// Apply to all routes in the group
adminGroup := r.Group("/admin",
option.GroupTags("Administration"),
option.GroupSecurity("bearerAuth"),
option.GroupDeprecated(),
)// Hide internal routes from documentation
internalGroup := r.Group("/internal",
option.GroupHidden(),
)
```## Advanced Features
### Rich Schema Documentation
```go
type CreateUserRequest struct {
Name string `json:"name" required:"true" minLength:"2" maxLength:"50"`
Email string `json:"email" required:"true" format:"email"`
Age int `json:"age" minimum:"18" maximum:"120"`
Tags []string `json:"tags" maxItems:"10"`
}
```For comprehensive struct tag documentation, see [swaggest/openapi-go](https://github.com/swaggest/openapi-go?tab=readme-ov-file#features) and [swaggest/jsonschema-go](https://github.com/swaggest/jsonschema-go?tab=readme-ov-file#field-tags).
### Generic Response Types
```go
type APIResponse[T any] struct {
Success bool `json:"success"`
Data T `json:"data,omitempty"`
Error string `json:"error,omitempty"`
Timestamp string `json:"timestamp"`
}// Usage
option.Response(200, new(APIResponse[User]))
option.Response(200, new(APIResponse[[]Product]))
```## Examples
Explore complete working examples in the [`examples/`](examples/) directory:
- **[Basic](examples/basic/)** — Standalone spec generation
- **[Petstore](examples/petstore/)** — Full Petstore API with routes and models## API Reference
Complete documentation at [pkg.go.dev/github.com/oaswrap/spec](https://pkg.go.dev/github.com/oaswrap/spec).
Key packages:
- [`spec`](https://pkg.go.dev/github.com/oaswrap/spec) — Core router and spec builder
- [`option`](https://pkg.go.dev/github.com/oaswrap/spec/option) — Configuration options## FAQ
**Q: Can I use this with my existing API?**
A: Absolutely! Use the standalone version to document existing APIs, or gradually migrate to framework adapters.**Q: How does this compare to swag/swaggo?**
A: While swag uses code comments, oaswrap uses pure Go code for type safety and better IDE support. Both have their merits - swag is annotation-based while oaswrap is code-first.**Q: How does this compare to Huma?**
A: Both are excellent choices with different philosophies:
- **Huma** is a complete HTTP framework with built-in OpenAPI generation, validation, and middleware
- **oaswrap/spec** is a lightweight, framework-agnostic documentation builder that works with your existing setup
- Use **Huma** if you're building a new API and want an all-in-one solution with automatic validation
- Use **oaswrap** if you have existing code, prefer framework flexibility, or need standalone spec generation**Q: Can I customize the generated documentation UI?**
A: Framework adapters provide built-in UIs, but you can serve the spec with any OpenAPI-compatible tool like Swagger UI, Redoc, or Stoplight.**Q: Is this production ready?**
A: The library is in active development. While core functionality is solid, consider it beta software. Thorough testing is recommended before production use.**Q: How do I handle authentication in the generated docs?**
A: Define security schemes using `option.WithSecurity()` and apply them to routes with `option.Security()`. The generated docs will include authentication UI.## Roadmap
- [ ] Redoc UI support
- [ ] Stoplight Elements integration## Contributing
We welcome contributions! Here's how you can help:
1. **🐛 Report bugs** — Open an issue with reproduction steps
2. **💡 Suggest features** — Share your ideas for improvements
3. **📝 Improve docs** — Help make our documentation clearer
4. **🔧 Submit PRs** — Fix bugs or add featuresPlease check existing issues and discussions before starting work on new features.
## License
[MIT License](LICENSE) — Created with ❤️ by [Ahmad Faiz](https://github.com/afkdevs).