https://github.com/go-swagno/swagno
Generate Swagger 2.0 or OpenAPI 3.0 documentation for Go with "no" annotations, "no" files, "no" command
https://github.com/go-swagno/swagno
go golang openapi openapi-codegen openapi-documentation openapi-generator openapi-specification openapi3 swagger swagger-ui swagger2 without-annotations without-files without-run
Last synced: about 2 months ago
JSON representation
Generate Swagger 2.0 or OpenAPI 3.0 documentation for Go with "no" annotations, "no" files, "no" command
- Host: GitHub
- URL: https://github.com/go-swagno/swagno
- Owner: go-swagno
- License: mit
- Created: 2022-09-01T08:27:06.000Z (almost 4 years ago)
- Default Branch: master
- Last Pushed: 2026-03-11T23:26:27.000Z (3 months ago)
- Last Synced: 2026-03-12T04:35:43.672Z (3 months ago)
- Topics: go, golang, openapi, openapi-codegen, openapi-documentation, openapi-generator, openapi-specification, openapi3, swagger, swagger-ui, swagger2, without-annotations, without-files, without-run
- Language: Go
- Homepage:
- Size: 835 KB
- Stars: 109
- Watchers: 2
- Forks: 19
- Open Issues: 9
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Swagno: _`no` annotations, `no` files, `no` commands_

Swagno redefines the way API documentation is created, embedding documentation seamlessly into your codebase for a clutter-free, streamlined experience. This tool does away with the hassles of annotations, exported files, and command executions. Simplify your documentation process with Swagno. Embrace the ease: Swagno - no annotations, no exports, no commands!
**🚀 Now supports both Swagger 2.0 and [OpenAPI 3.0](https://github.com/go-swagno/swagno/v3)!**
## About the Project
This project inspired by [Swaggo](https://github.com/swaggo/swag). Swaggo, uses annotations, exports files and needs to run by command. If you don't like this way, [Swag**no**](https://github.com/go-swagno/swagno) appears as a good alternative.
## Versions
Swagno supports both specification versions:
- **v2 (default)**: Swagger 2.0 specification - Use the main package `github.com/go-swagno/swagno`
- **v3**: OpenAPI 3.0.3 specification - Use the v3 package `github.com/go-swagno/swagno/v3`
### OpenAPI 3.0 Support 🆕
Starting with v3, Swagno now supports OpenAPI 3.0.3 specification with enhanced features:
```go
// OpenAPI 3.0 usage
import swagno3 "github.com/go-swagno/swagno/v3"
openapi := swagno3.New(swagno3.Config{
Title: "My API",
Version: "v1.0.0",
})
openapi.AddServer("https://api.example.com/v1", "Production server")
openapi.SetBearerAuth("JWT", "Bearer authentication")
```
**New OpenAPI 3.0 Features:**
- ✅ Multiple servers support
- ✅ Enhanced security schemes (Bearer, OpenID Connect)
- ✅ Proper request body handling with content types
- ✅ Improved schema definitions with nullable, readOnly, writeOnly
- ✅ Better parameter validation and examples
- ✅ Components-based architecture
[📖 See v3 documentation](v3/README.md) for detailed OpenAPI 3.0 usage and migration guide.
## Contents
- [Examples](example/)
- [Getting started](#getting-started)
- [Supported Web Frameworks](#supported-web-frameworks)
- [Implementation Status](#implementation-status)
- [Create Your Swagger](#create-your-swagger)
- [General Swagger Info](#general-swagger-info)
- [Endpoints (API)](#endpoints-api)
- [Endpoint Options](#endpoint-options)
- [Parameters](#parameters)
- [Parameter Location](#parameter-location)
- [Parameter Types](#parameter-types)
- [Parameter Options](#parameter-options)
- [Defining Models](#defining-models)
- [Security](#security-optional)
- [Contribution](#contribution)
## Getting started
0. Server Example [here](example/http/server.go)
1. Get swagno package in your project
```sh
go get github.com/go-swagno/swagno
```
2. Import swagno
```go
import "github.com/go-swagno/swagno"
import "github.com/go-swagno/swagno-http/swagger" // recommended if you want to use go-swagno http handler for serving swagger docs
```
3. Create your endpoints (check [Endpoints](#endpoints-api)) with it's corresponding parameters. Example:
```go
endpoints := []*endpoint.EndPoint{
endpoint.New(
endpoint.GET,
"/product/page",
endpoint.WithTags("product"),
endpoint.WithSuccessfulReturns([]response.Response{response.New(models.EmptySuccessfulResponse{}, "OK", "200")}),
endpoint.WithErrors([]response.Response{response.New(models.UnsuccessfulResponse{}, "Bad Request", "400")}),
endpoint.WithDescription(desc),
endpoint.WithProduce([]mime.MIME{mime.JSON, mime.XML}),
endpoint.WithConsume([]mime.MIME{mime.JSON}),
),
endpoint.New(
endpoint.GET,
"/product",
endpoint.WithTags("product"),
endpoint.WithParams(parameter.IntParam("id", parameter.WithRequired())),
endpoint.WithSuccessfulReturns([]response.Response{response.New(models.EmptySuccessfulResponse{}, "OK", "200")}),
endpoint.WithErrors([]response.Response{response.New(models.UnsuccessfulResponse{}, "Bad Request", "400")}),
),
endpoint.New(
endpoint.GET,
"/product/{id}/detail",
endpoint.WithTags("product"),
endpoint.WithParams(parameter.IntParam("id", parameter.WithRequired())),
endpoint.WithSuccessfulReturns([]response.Response{response.New(models.EmptySuccessfulResponse{}, "OK", "200")}),
endpoint.WithErrors([]response.Response{response.New(models.UnsuccessfulResponse{}, "Bad Request", "400")}),
),
endpoint.New(
endpoint.POST,
"/product",
endpoint.WithTags("product"),
endpoint.WithBody(models.ProductPost{}),
endpoint.WithSuccessfulReturns([]response.Response{response.New(models.EmptySuccessfulResponse{}, "OK", "200")}),
endpoint.WithErrors([]response.Response{response.New(models.UnsuccessfulResponse{}, "Bad Request", "400")}),
endpoint.WithProduce([]mime.MIME{mime.JSON, mime.XML}),
),
}
```
4. Create Swagger(swagno) instance
```go
sw := swagno.New(swagno.Config{Title: "Testing API", Version: "v1.0.0", Host: "localhost:8080"})
```
5. Use sw.AddEndpoints function to add endpoints arrays to Swagno
```go
sw.AddEndpoints(endpoints)
// you can also add more arrays
sw.AddEndpoints(productEndpoints)
sw.AddEndpoints(merchantEndpoints)
```
6. Generate json as string and give it to your handler to serve. You can create your own handler or use the swagno http handler
```go
http.HandleFunc("/swagger/", swagger.SwaggerHandler(sw.MustToJson()))
fmt.Println("Server is running on http://localhost:8080")
http.ListenAndServe(":8080", nil)
```
## Supported Web Frameworks
- [fiber](https://github.com/go-swagno/swagno-fiber)
- [gin](https://github.com/go-swagno/swagno-gin)
- [gorilla/mux](https://github.com/go-swagno/swagno-http)
- [net/http](https://github.com/go-swagno/swagno-http)
## How to use with Fiber
You can read detailed document and find better examples in [swagno-fiber](https://github.com/go-swagno/swagno-fiber)
Example:
1. Get swagno-fiber
```sh
go get github.com/go-swagno/swagno-fiber
```
2. Import swagno-fiber
```go
import "github.com/go-swagno/swagno-fiber/swagger"
```
3.
```go
...
// assume you declare your endpoints and "sw"(swagno) instance
swagger.SwaggerHandler(a, sw.MustToJson(), swagger.WithPrefix("/swagger"))
...
```
You can find a detailed example in [https://github.com/go-swagno/swagno/example/fiber](https://github.com/go-swagno/swagno/tree/master/example/fiber)
## How to use with Gin
You can read detailed document and find better examples in [swagno-gin](https://github.com/go-swagno/swagno-gin)
Example:
1. Get swagno-gin
```sh
go get github.com/go-swagno/swagno-gin
```
2. Import swagno-gin
```go
import "github.com/go-swagno/swagno-gin/swagger"
```
3.
```go
...
// assume you declare your endpoints and "sw"(swagno) instance
a.GET("/swagger/*any", swagger.SwaggerHandler(sw.MustToJson()))
...
```
You can find a detailed example in [https://github.com/go-swagno/swagno/example/gin](https://github.com/go-swagno/swagno/tree/master/example/gin)
## Implementation Status
As purpose of this section, you can compare **swagno** status with **swaggo**
[Swagger 2.0 document](https://swagger.io/docs/specification/2-0/basic-structure/)
See how Swagno compares to Swaggo in terms of Swagger 2.0 features:
- Basic Structure: ✅
- API Host and Base Path: ✅
- Paths and Operations: ✅
- Describing Parameters: ✅
- Describing Request Body: ✅
- Describing Responses: ✅
- MIME Types: 🔄 (Improvement needed)
- Authentication: ✅
- File Upload: 🔄 (Improvement needed)
- Enums: ✅
- Grouping Operations With Tags: ✅
- Swagger Extensions: 🔜 (Coming soon)
- Swagger Validation: 🔜 (Coming soon)
# Create Your Swagger
## General Swagger Info
Swagger v2.0 specifications can be found [here](https://swagger.io/specification/v2/)
You can use the swagger config when creating new swagger object
```go
type Config struct {
Title string // title of the Swagger documentation
Version string // version of the Swagger documentation
Description string // description of the Swagger documentation
Host string // host URL for the API
Path string // path to the Swagger JSON file
License *License // license information for the Swagger documentation
Contact *Contact // contact information for the Swagger documentation
TermsOfService string // term of service information for the Swagger documentation
}
```
```go
sw := swagno.New(swagno.Config{Title: "Testing API", Version: "v1.0.0", Host: "localhost:8080"}) // optionally you can also use the License and Info properties as well
```
## Endpoints (API)
Definition:
```go
type EndPoint struct {
method string
path string
params []*parameter.Parameter
tags []string
Body interface{}
successfulReturns []response.Info
errors []response.Info
description string
summary string
consume []mime.MIME
produce []mime.MIME
security []map[string][]string
}
```
You need to create an Endpoint array []Endpoint and add your endpoints in this array. Example:
```go
import "github.com/go-swagno/swagno/components/endpoint"
endpoints := []*endpoint.EndPoint{
endpoint.New(
endpoint.POST,
"/product",
endpoint.WithTags("product"),
endpoint.WithBody(models.ProductPost{}),
endpoint.WithSuccessfulReturns([]response.Info{models.SuccessfulResponse{}}),
endpoint.WithErrors([]response.Info{models.UnsuccessfulResponse{}}),
endpoint.WithProduce([]mime.MIME{mime.JSON, mime.XML}),
),
}
// add endpoints array to Swagno
sw.AddEndpoints(endpoints)
```
**Note:** You can simply add only one endpoint by using `AddEndpoint(endpoint)`
### Endpoint Options
Arguments: The `EndPoint` object is configured via the `With` functional options provided in the `github.com/go-swagno/swagno/components/endpoint package`
| Function | Description |
| ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| `WithParams(params []*parameter.Parameter)` | Adds parameters to the `EndPoint`. |
| `WithTags(tags ...string)` | Assigns tags to the `EndPoint` for grouping and categorization. |
| `WithBody(body interface{})` | Sets the request body structure expected by the `EndPoint`. |
| `WithSuccessfulReturns(successfulReturns ...response.Info)` | Sets the successful responses from the `EndPoint`. Needs to implement the `response.Info` interface |
| `WithErrors(errors ...response.Info)` | Sets the error responses the `EndPoint` could return. Needs to implement the `response.Info` interface |
| `WithDescription(description string)` | Provides a detailed description of what the `EndPoint` does. |
| `WithSummary(summary string)` | Gives a brief summary of the `EndPoint` purpose. |
| `WithConsume(consume ...mime.MIME)` | Sets the MIME types the `EndPoint` can consume (input formats). |
| `WithProduce(produce ...mime.MIME)` | Sets the MIME types the `EndPoint` can produce (output formats). |
| `WithSecurity(security ...map[string][]string)` | Sets security requirements for the `EndPoint`, such as required scopes or auth methods. |
❗ **Don't forget to add your endpoints array to Swagno prior to serving requests** ❗
```go
sw.AddEndpoints(endpoints)
```
### Parameters
You can use `endpoint.WithParams()` function to generate params array for an `Endpoint` object:
```go
// path should be -> /product/{merchant}/{id}
endpoint.WithParams(
parameter.StrParam("id", parameter.WithIn(parameter.Path), parameter.WithRequired()),
parameter.StrParam("merchant", parameter.WithIn(parameter.Path), parameter.WithRequired()),
),
```
### Parameter Location
Each parameter value can be assigned to a different location for the api request (i.e. [query, header, path, form]) using `WithIn`
```go
parameter.WithIn(parameter.Query)
```
| Location Type | Description |
| ------------- | ----------------------------------------------------------------- |
| `Query` | Used for parameters in the URL query string. |
| `Header` | Used for parameters in the HTTP header. |
| `Path` | Used for parameters within the path of the URL. |
| `Form` | Used for parameters submitted through form data in POST requests. |
#### Parameter Types
Below are all the parameter types that the `EndPoint object can take as input`
| Function Signature | Description |
| ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| `func IntParam(name string, l Location, opts ...Option) *Parameter` | Creates an integer parameter with a specified name and location, accepting additional options. |
| `func StrParam(name string, l Location, opts ...Option) *Parameter` | Creates a string parameter with the given name and location, also taking variable options. |
| `func BoolParam(name string, l Location, opts ...Option) *Parameter` | Constructs a boolean parameter identified by name and location, allowing extra options to be passed. |
| `func FileParam(name string, opts ...Option) *Parameter` | Generates a file parameter using the provided name and options, typically used for file uploads. |
| `func IntEnumParam(name string, l Location, arr []int64, opts ...Option) *Parameter` | Creates an integer parameter that allows a set of enumerated values, specified by the array `arr`. |
| `func StrEnumParam(name string, l Location, arr []string, opts ...Option) *Parameter` | Produces a string parameter with a restricted set of possible values defined by the string array `arr`. |
| `func IntArrParam(name string, l Location, arr []int64, opts ...Option) *Parameter` | Establishes an integer array parameter, where the array represents multiple values for the parameter. |
### Parameter Options
Just like the `endpoint` package, the `parameter` package also comes with a set of functional `With` options to configure a parameter.
| Modifier Function | Description |
| ------------------------------------------ | ------------------------------------------------------------------ |
| `WithType(t ParamType)` | Sets the type of a parameter (integer, string, boolean, and etc.). |
| `WithIn(in Location)` | Defines where the parameter is expected (query, header). |
| `WithRequired()` | Makes the parameter required. |
| `WithDescription(description string)` | Provides a description for the parameter. |
| `WithDefault(defaultValue interface{})` | Sets a default value for the parameter. |
| `WithFormat(format string)` | Sets the format field for the parameter. |
| `WithMin(min int)` | sets the Min field of a Parameter. |
| `WithMax(max int)` | sets the Max field of a Parameter. |
| `WithMinLen(minLen int)` | sets the MinLen field of a Parameter. |
| `WithMaxLen(maxLen int)` | sets the MaxLen field of a Parameter. |
| `WithPattern(pattern string)` | sets the Pattern field of a Parameter. |
| `WithMaxItems(maxItems int)` | sets the WithMaxItems field of a Parameter. |
| `WithMinItems(minItems int)` | sets the WithMinItems field of a Parameter. |
| `WithUniqueItems(uniqueItems bool)` | Sets the WithUniqueItems filed of a Parameter |
| `WithMultipleOf(multipleOf int64)` | Sets the WithMultipleOf filed of a Parameter |
| `WithCollectionFormat(c CollectionFormat)` | Sets the WithCollectionFormat filed of a Parameter |
## Defining Models
The `response.New()` function allows for creating custom response models with a flexible data structure (model any), an associated return code, and a descriptive message, enabling tailored responses for successful outcomes and error cases in an API endpoint configuration.
```go
package response
func response.New(model any, returnCode string, description string) CustomResponse
```
Example shown below
```go
package response
[]*endpoint.EndPoint{
endpoint.New(
...
endpoint.WithSuccessfulReturns([]response.Response{response.New(models.SuccessfulResponse{}, "Request Accepted", "201")}),
endpoint.WithErrors([]response.Response{response.New(models.UnsuccessfulResponse{}, "Bad Request", "400")}),
...
)
}
```
If you want to avoid using the helper function above you can pass in any struct as long as it's implements the `Response` interface shown below.
```go
package response
// Response is an interface for response information.
type Response interface {
Description() string
ReturnCode() string
}
```
### Successful Response/Return
use a struct model instance like `models.EmptySuccessfulResponse{}` or nil
### Error Response
use a struct model instance like `models.UnsuccessfulResponse{}` or nil
### Request Body
use a struct model instance like `models.PostBody{}` or nil
### Security (optional)
Also provides functions to set different security configurations for swagger doc
```go
sw.SetBasicAuth()
sw.SetApiKeyAuth("api_key", "query")
sw.SetOAuth2Auth("oauth2_name", "password", "http://localhost:8080/oauth2/token", "http://localhost:8080/oauth2/authorize", security.Scopes(security.Scope("read:pets", "read your pets"), security.Scope("write:pets", "modify pets in your account")))
```
### Required Fields
non-pointer fields will be shown in swagger model as required. In addition, fields with `omitempty` tag will **not** be required by default. If you want to add required to a field you can add struct tag as `required:"true"`.
```go
type Model struct {
Foo uint64 `json:"foo"`
Baz uint64 `json:"foo,omitempty" required:"true"`
Boo *string `json:"boo" required:"true"`
Bar interface{} `json:"bar" required:"true"`
}
```
# Contribution
We are welcome to any contribution. Swagno still has some missing features. Also we want to enrich handler implementations for other web frameworks.