Skip to content
Snippets Groups Projects
oapi.go 1.58 KiB
Newer Older
package cmd

import (
	"net/http"
	"strconv"

	"github.com/getkin/kin-openapi/openapi2"
	"github.com/getkin/kin-openapi/openapi3"
)

type OpenAPIFile interface {
	Info() *openapi3.Info
	JSON() []byte
}

type openAPI2File struct {
	oapi *openapi2.T
	json []byte
}

func (f *openAPI2File) Info() *openapi3.Info {
	return &f.oapi.Info
}

func (f *openAPI2File) JSON() []byte {
	if f.json == nil {
		b, err := f.oapi.MarshalJSON()
		if err != nil {
			panic(err)
		}
		f.json = b
	}
Christophe de Vienne's avatar
Christophe de Vienne committed

	return f.json
}

type openAPI3File struct {
	oapi *openapi3.T
	json []byte
}

func (f *openAPI3File) Info() *openapi3.Info {
	return f.oapi.Info
}

func (f *openAPI3File) JSON() []byte {
	if f.json == nil {
		b, err := f.oapi.MarshalJSON()
		if err != nil {
			panic(err)
		}
		f.json = b
	}
Christophe de Vienne's avatar
Christophe de Vienne committed

func WithOpenAPI2[E any](t *openapi2.T) Option[E] {
	return WithOpenAPI[E](&openAPI2File{t, nil})
func WithOpenAPI3[E any](t *openapi3.T) Option[E] {
	return WithOpenAPI[E](&openAPI3File{t, nil})
func WithOpenAPI[E any](oapi OpenAPIFile) Option[E] {
	return func(program *Program[E]) {
		program.Version.APIVersion = oapi.Info().Title + " " + oapi.Info().Version
		WithMiddleware[E](func(next http.Handler) http.Handler {
			return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
				if r.URL.Path == "/swagger.json" {
					json := oapi.JSON()
					rw.Header().Set("Content-Type", "application/json")
Christophe de Vienne's avatar
Christophe de Vienne committed
					rw.Header().Set("Content-Length", strconv.Itoa(len(json)))
					rw.WriteHeader(http.StatusOK)
					_, _ = rw.Write(oapi.JSON())
				} else {
					next.ServeHTTP(rw, r)
				}
			})
		})(program)
	}
}