Swagno redefines the way Swagger Documentation 2.0 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!
This project inspired by Swaggo. Swaggo, uses annotations, exports files and needs to run by command. If you don't like this way, Swagno appears as a good alternative.
- Examples
- Getting started
- Supported Web Frameworks
- Implementation Status
- Create Your Swagger
- Contribution
-
Server Example here
-
Get swagno package in your project
go get github.com/go-swagno/swagno- Import swagno
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- Create your endpoints (check Endpoints) with it's corresponding parameters. Example:
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}),
),
}- Create Swagger(swagno) instance
sw := swagno.New(swagno.Config{Title: "Testing API", Version: "v1.0.0", Host: "localhost:8080"})- Use sw.AddEndpoints function to add endpoints arrays to Swagno
sw.AddEndpoints(endpoints)
// you can also add more arrays
sw.AddEndpoints(productEndpoints)
sw.AddEndpoints(merchantEndpoints)- Generate json as string and give it to your handler to serve. You can create your own handler or use the swagno http handler
http.HandleFunc("/swagger/", swagger.SwaggerHandler(sw.MustToJson()))
fmt.Println("Server is running on http://localhost:8080")
http.ListenAndServe(":8080", nil)You can read detailed document and find better examples in swagno-fiber
Example:
- Get swagno-fiber
go get github.com/go-swagno/swagno-fiber- Import swagno-fiber
import "github.com/go-swagno/swagno-fiber/swagger"...
// 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
You can read detailed document and find better examples in swagno-gin
Example:
- Get swagno-gin
go get github.com/go-swagno/swagno-gin- Import swagno-gin
import "github.com/go-swagno/swagno-gin/swagger"...
// 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
As purpose of this section, you can compare swagno status with swaggo
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)
Swagger v2.0 specifications can be found here
You can use the swagger config when creating new swagger object
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
}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 wellDefinition:
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:
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)
Arguments: The EndPoint object is configured via the With<property> 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 ❗
sw.AddEndpoints(endpoints)You can use endpoint.WithParams() function to generate params array for an Endpoint object:
// 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()),
),Each parameter value can be assigned to a different location for the api request (i.e. [query, header, path, form]) using WithIn
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. |
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. |
Just like the endpoint package, the parameter package also comes with a set of functional With<Option> 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 |
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.
package response
func response.New(model any, returnCode string, description string) CustomResponseExample shown below
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.
package response
// Response is an interface for response information.
type Response interface {
Description() string
ReturnCode() string
}use a struct model instance like models.EmptySuccessfulResponse{} or nil
use a struct model instance like models.UnsuccessfulResponse{} or nil
use a struct model instance like models.PostBody{} or nil
Also provides functions to set different security configurations for swagger doc
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")))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".
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"`
}We are welcome to any contribution. Swagno still has some missing features. Also we want to enrich handler implementations for other web frameworks.
