swagger

package module
v0.10.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 28, 2024 License: MIT Imports: 11 Imported by: 5

README

Build Status Coverage Status Go Report Card GoDoc

gswagger

Generate an openapi spec dynamically based on the types used to handle request and response.

It works with any router, it is simple to add support to your router implementing the apirouter interface.

The routers supported out of the box are:

This lib uses kin-openapi to automatically generate and serve a swagger file.

To convert struct to schemas, we use jsonschema library.
The struct must contains the appropriate struct tags to be inserted in json schema to generate the schema dynamically.
It is always possible to add a totally custom swagger schema using kin-openapi.

Install

To use it, install with

go get github.com/davidebianchi/gswagger

Usage

An example usage of this lib with gorilla mux:

context := context.Background()
muxRouter := mux.NewRouter()

router, _ := swagger.NewRouter(gorilla.NewRouter(muxRouter), swagger.Options{
  Context: context,
  Openapi: &openapi3.T{
    Info: &openapi3.Info{
      Title:   "my title",
      Version: "1.0.0",
    },
  },
})

okHandler := func(w http.ResponseWriter, req *http.Request) {
  w.WriteHeader(http.StatusOK)
  w.Write([]byte("OK"))
}

type User struct {
  Name        string   `json:"name" jsonschema:"title=The user name,required" jsonschema_extras:"example=Jane"`
  PhoneNumber int      `json:"phone" jsonschema:"title=mobile number of user"`
  Groups      []string `json:"groups,omitempty" jsonschema:"title=groups of the user,default=users"`
  Address     string   `json:"address" jsonschema:"title=user address"`
}
type errorResponse struct {
  Message string `json:"message"`
}

router.AddRoute(http.MethodPost, "/users", okHandler, swagger.Definitions{
  RequestBody: &swagger.ContentValue{
    Content: swagger.Content{
      "application/json": {Value: User{}},
    },
  },
  Responses: map[int]swagger.ContentValue{
    201: {
      Content: swagger.Content{
        "text/html": {Value: ""},
      },
    },
    401: {
      Content: swagger.Content{
        "application/json": {Value: &errorResponse{}},
      },
      Description: "invalid request",
    },
  },
})

router.AddRoute(http.MethodGet, "/users", okHandler, swagger.Definitions{
  Responses: map[int]swagger.ContentValue{
    200: {
      Content: swagger.Content{
        "application/json": {Value: &[]User{}},
      },
    },
  },
})

carSchema := openapi3.NewObjectSchema().WithProperties(map[string]*openapi3.Schema{
  "foo": openapi3.NewStringSchema(),
  "bar": openapi3.NewIntegerSchema().WithMax(15).WithMin(5),
})
requestBody := openapi3.NewRequestBody().WithJSONSchema(carSchema)
operation := swagger.NewOperation()
operation.AddRequestBody(requestBody)

router.AddRawRoute(http.MethodPost, "/cars", okHandler, operation)

router.GenerateAndExposeOpenapi()

This configuration will output the schema shown here.

Auto generated path params schema

The path params, if not set in schema, are auto generated from the path. The format of the path parameters depends on the router library you are using, as explained below.

Gorilla Mux

Gorilla Mux supports the path parameters as {someParam}, for example as in /users/{userId}.

Here is the example test.

The generated oas schema will contains userId, carId and driverId as path params set to string. If only one params is set, you must specify manually all the path params.

The generated OAS for this test case is visible here.

Fiber

Fiber supports the path parameters as :someParam, for example as in /users/:userId.

Here is the example test

SubRouter

It is possible to create a new sub router from the swagger.Router. It is possible to add a prefix to all the routes created under the specific router (instead of use the router specific methods, if given, or repeat the prefix for every route).

It could also be useful if you need a sub router to create a group of APIs which use the same middleware (for example,this could be achieved by the SubRouter features of gorilla mux, for example).

To see the SubRouter example, please see the integration test of one of the supported routers.

FAQ
  1. How to add format binary? Formats date-time, email, hostname, ipv4, ipv6, uri could be added with tag jsonschema. Others format could be added with tag jsonschema_extra. Not all the formats are supported (see discovered unsupported formats here).

  2. How to add a swagger with allOf? You can create manually a swagger with allOf using the AddRawRoute method.

  3. How to add a swagger with anyOf? You can create manually a swagger with anyOf using the AddRawRoute method.

  4. How to add a swagger with oneOf? You can create manually a swagger with oneOf using the AddRawRoute method, or use the jsonschema struct tag.

Discovered unsupported schema features

Formats:

Versioning

We use SemVer for versioning. For the versions available, see the tags on this repository.

Documentation

Index

Constants

View Source
const (
	// DefaultJSONDocumentationPath is the path of the swagger documentation in json format.
	DefaultJSONDocumentationPath = "/documentation/json"
	// DefaultYAMLDocumentationPath is the path of the swagger documentation in yaml format.
	DefaultYAMLDocumentationPath = "/documentation/yaml"
)

Variables

View Source
var (
	// ErrGenerateSwagger throws when fails the marshalling of the swagger struct.
	ErrGenerateSwagger = errors.New("fail to generate swagger")
	// ErrValidatingSwagger throws when given swagger params are not correct.
	ErrValidatingSwagger = errors.New("fails to validate swagger")
)
View Source
var (
	// ErrResponses is thrown if error occurs generating responses schemas.
	ErrResponses = errors.New("errors generating responses schema")
	// ErrRequestBody is thrown if error occurs generating responses schemas.
	ErrRequestBody = errors.New("errors generating request body schema")
	// ErrPathParams is thrown if error occurs generating path params schemas.
	ErrPathParams = errors.New("errors generating path parameters schema")
	// ErrQuerystring is thrown if error occurs generating querystring params schemas.
	ErrQuerystring = errors.New("errors generating querystring schema")
)

Functions

This section is empty.

Types

type Content

type Content map[string]Schema

Content is the type of a content. The key of the map define the content-type.

type ContentValue

type ContentValue struct {
	Content     Content
	Description string
}

ContentValue is the struct containing the content information.

type Definitions

type Definitions struct {
	// Specification extensions https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specification-extensions
	Extensions map[string]interface{}
	// Optional field for documentation
	Tags        []string
	Summary     string
	Description string
	Deprecated  bool

	// PathParams contains the path parameters. If empty is autocompleted from the path
	PathParams  ParameterValue
	Querystring ParameterValue
	Headers     ParameterValue
	Cookies     ParameterValue
	RequestBody *ContentValue
	Responses   map[int]ContentValue

	Security SecurityRequirements
}

Definitions of the route. To see how to use, refer to https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md

type Operation

type Operation struct {
	*openapi3.Operation
}

Operation type

func NewOperation

func NewOperation() Operation

NewOperation returns an OpenApi operation.

func (*Operation) AddRequestBody

func (o *Operation) AddRequestBody(requestBody *openapi3.RequestBody)

AddRequestBody set request body into operation.

func (*Operation) AddResponse

func (o *Operation) AddResponse(status int, response *openapi3.Response)

AddResponse add response to operation. It check if the description is present (otherwise default to empty string). This method does not add the default response, but it is always possible to add it manually.

type Options

type Options struct {
	Context context.Context
	Openapi *openapi3.T
	// JSONDocumentationPath is the path exposed by json endpoint. Default to /documentation/json.
	JSONDocumentationPath string
	// YAMLDocumentationPath is the path exposed by yaml endpoint. Default to /documentation/yaml.
	YAMLDocumentationPath string
	// Add path prefix to add to every router path.
	PathPrefix string
}

Options to be passed to create the new router and swagger

type Parameter added in v0.5.0

type Parameter struct {
	Content     Content
	Schema      *Schema
	Description string
}

type ParameterValue

type ParameterValue map[string]Parameter

ParameterValue is the struct containing the schema or the content information. If content is specified, it takes precedence.

type Router

type Router[HandlerFunc, Route any] struct {
	// contains filtered or unexported fields
}

Router handle the api router and the swagger schema. api router supported out of the box are: - gorilla mux

func NewRouter

func NewRouter[HandlerFunc, Route any](router apirouter.Router[HandlerFunc, Route], options Options) (*Router[HandlerFunc, Route], error)

NewRouter generate new router with swagger. Default to OpenAPI 3.0.0

func (Router[HandlerFunc, Route]) AddRawRoute

func (r Router[HandlerFunc, Route]) AddRawRoute(method string, routePath string, handler HandlerFunc, operation Operation) (Route, error)

AddRawRoute add route to router with specific method, path and handler. Add the router also to the swagger schema, after validating it

func (Router[HandlerFunc, Route]) AddRoute

func (r Router[HandlerFunc, Route]) AddRoute(method string, path string, handler HandlerFunc, schema Definitions) (Route, error)

AddRoute add a route with json schema inferred by passed schema.

func (Router[_, _]) GenerateAndExposeOpenapi added in v0.7.0

func (r Router[_, _]) GenerateAndExposeOpenapi() error

GenerateAndExposeOpenapi creates a /documentation/json route on router and expose the generated swagger

func (Router[HandlerFunc, Route]) SubRouter added in v0.3.0

func (r Router[HandlerFunc, Route]) SubRouter(router apirouter.Router[HandlerFunc, Route], opts SubRouterOptions) (*Router[HandlerFunc, Route], error)

type Schema

type Schema struct {
	Value                     interface{}
	AllowAdditionalProperties bool
}

Schema contains the value and if properties allow additional properties.

type SecurityRequirement added in v0.9.0

type SecurityRequirement map[string][]string

type SecurityRequirements added in v0.9.0

type SecurityRequirements []SecurityRequirement

type SubRouterOptions added in v0.3.0

type SubRouterOptions struct {
	PathPrefix string
}

Directories

Path Synopsis
support

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL