package builder import ( "net/http" "strconv" "github.com/invopop/jsonschema" ) type PathOption func(map[string]interface{}) type Builder interface { AddPath(string) PathBuilder Build() *Document } type PathBuilder interface { Get(string, string, ...PathOption) } type builder struct { doc *Document } type pathBuilder struct { root string builder *builder } func (b *pathBuilder) Get(description string, summary string, options ...PathOption) { get := map[string]interface{}{ "description": description, "summary": summary, "parameters": []interface{}{}, "responses": map[string]interface{}{}, } for _, option := range options { option(get) } paths := b.builder.doc.Paths paths[b.root] = map[string]interface{}{ "get": get, } } func New(title, version string) Builder { return &builder{ doc: &Document{ Version: "3.1.0", Info: &Info{ Title: title, Version: version, }, Paths: Paths{}, }, } } func (b *builder) AddPath(path string) PathBuilder { return &pathBuilder{ root: path, builder: b, } } func (b *builder) Build() *Document { return b.doc } func WithResponse(status int, mediaType string, schema *jsonschema.Schema) PathOption { return func(paths map[string]interface{}) { responses := paths["responses"].(map[string]interface{}) if value, ok := responses[strconv.Itoa(status)]; ok { response := value.(map[string]interface{}) response["content"].(map[string]interface{})[mediaType] = map[string]*jsonschema.Schema{ "schema": schema, } } else { responses[strconv.Itoa(status)] = map[string]interface{}{ "description": http.StatusText(status), "content": map[string]interface{}{ mediaType: map[string]*jsonschema.Schema{ "schema": schema, }, }, } } } } func WithParameter(in string, name string, schema *jsonschema.Schema) PathOption { return func(paths map[string]interface{}) { params := paths["parameters"].([]interface{}) params = append(params, map[string]interface{}{ "in": in, "name": name, "schema": schema, }) paths["parameters"] = params } }