gf/protocol/goai/goai.go

152 lines
4.5 KiB
Go
Raw Normal View History

2021-10-02 18:54:06 +08:00
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
// Package goai implements and provides document generating for OpenApi specification.
//
// https://editor.swagger.io/
2021-10-02 14:52:28 +08:00
package goai
import (
"context"
2021-10-02 18:54:06 +08:00
"fmt"
2021-10-02 14:52:28 +08:00
"github.com/gogf/gf/errors/gcode"
"github.com/gogf/gf/errors/gerror"
"github.com/gogf/gf/internal/intlog"
"github.com/gogf/gf/internal/json"
2021-10-06 21:51:21 +08:00
"github.com/gogf/gf/text/gstr"
2021-10-02 14:52:28 +08:00
"reflect"
)
// OpenApiV3 is the structure defined from:
2021-10-02 18:54:06 +08:00
// https://swagger.io/specification/
2021-10-02 14:52:28 +08:00
// https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md
type OpenApiV3 struct {
Config Config `json:"-" yaml:"-"`
OpenAPI string `json:"openapi" yaml:"openapi"`
Components Components `json:"components,omitempty" yaml:"components,omitempty"`
Info Info `json:"info" yaml:"info"`
Paths Paths `json:"paths" yaml:"paths"`
Security *SecurityRequirements `json:"security,omitempty" yaml:"security,omitempty"`
Servers *Servers `json:"servers,omitempty" yaml:"servers,omitempty"`
Tags *Tags `json:"tags,omitempty" yaml:"tags,omitempty"`
ExternalDocs *ExternalDocs `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"`
}
// ExternalDocs is specified by OpenAPI/Swagger standard version 3.0.
type ExternalDocs struct {
URL string `json:"url,omitempty"`
Description string `json:"description,omitempty"`
}
const (
HttpMethodAll = `ALL`
2021-10-02 14:52:28 +08:00
HttpMethodGet = `GET`
HttpMethodPut = `PUT`
HttpMethodPost = `POST`
HttpMethodDelete = `DELETE`
HttpMethodConnect = `CONNECT`
HttpMethodHead = `HEAD`
HttpMethodOptions = `OPTIONS`
HttpMethodPatch = `PATCH`
HttpMethodTrace = `TRACE`
)
const (
TypeNumber = `number`
TypeBoolean = `boolean`
TypeArray = `array`
TypeString = `string`
TypeObject = `object`
FormatInt32 = `int32`
FormatInt64 = `int64`
FormatDouble = `double`
FormatByte = `byte`
FormatBinary = `binary`
FormatDate = `date`
FormatDateTime = `date-time`
FormatPassword = `password`
)
2021-10-02 18:54:06 +08:00
const (
ParameterInHeader = `header`
ParameterInPath = `path`
ParameterInQuery = `query`
ParameterInCookie = `cookie`
)
const (
2021-10-08 16:02:53 +08:00
TagNamePath = `path`
TagNameMethod = `method`
TagNameIn = `in`
TagNameMime = `mime`
TagNameValidate = `v`
2021-10-02 18:54:06 +08:00
)
2021-10-02 15:07:47 +08:00
var (
defaultReadContentTypes = []string{`application/json`, `application/xml`}
defaultWriteContentTypes = []string{`application/json`, `application/xml`}
2021-10-02 14:52:28 +08:00
)
2021-10-02 18:54:06 +08:00
// New creates and returns a OpenApiV3 implements object.
2021-10-02 14:52:28 +08:00
func New() *OpenApiV3 {
oai := &OpenApiV3{}
oai.fillWithDefaultValue()
return oai
}
2021-10-02 18:54:06 +08:00
// AddInput is the structured parameter for function OpenApiV3.Add.
2021-10-02 14:52:28 +08:00
type AddInput struct {
2021-10-02 18:54:06 +08:00
Path string // Path specifies the custom path if this is not configured in Meta of struct tag.
2021-10-08 11:40:47 +08:00
Prefix string // Prefix specifies the custom route path prefix, which will be added with the path tag in Meta of struct tag.
2021-10-02 18:54:06 +08:00
Method string // Method specifies the custom HTTP method if this is not configured in Meta of struct tag.
Object interface{} // Object can be an instance of struct or a route function.
2021-10-02 14:52:28 +08:00
}
2021-10-02 18:54:06 +08:00
// Add adds an instance of struct or a route function to OpenApiV3 definition implements.
func (oai *OpenApiV3) Add(in AddInput) error {
2021-10-02 14:52:28 +08:00
var (
reflectValue = reflect.ValueOf(in.Object)
)
for reflectValue.Kind() == reflect.Ptr {
reflectValue = reflectValue.Elem()
}
switch reflectValue.Kind() {
case reflect.Struct:
2021-10-02 18:54:06 +08:00
return oai.addSchema(in.Object)
2021-10-02 14:52:28 +08:00
case reflect.Func:
2021-10-02 18:54:06 +08:00
return oai.addPath(addPathInput{
2021-10-02 14:52:28 +08:00
Path: in.Path,
2021-10-08 11:42:28 +08:00
Prefix: in.Prefix,
2021-10-02 14:52:28 +08:00
Method: in.Method,
Function: in.Object,
})
default:
2021-10-02 18:54:06 +08:00
return gerror.NewCodef(
2021-10-02 14:52:28 +08:00
gcode.CodeInvalidParameter,
`unsupported parameter type "%s", only struct/function type is supported`,
reflect.TypeOf(in.Object).String(),
2021-10-02 18:54:06 +08:00
)
2021-10-02 14:52:28 +08:00
}
}
func (oai OpenApiV3) String() string {
b, err := json.Marshal(oai)
if err != nil {
intlog.Error(context.TODO(), err)
}
return string(b)
}
2021-10-02 18:54:06 +08:00
func formatRefToBytes(ref string) []byte {
return []byte(fmt.Sprintf(`{"$ref":"#/components/schemas/%s"}`, ref))
}
2021-10-06 21:51:21 +08:00
func golangTypeToSchemaName(t reflect.Type) string {
return gstr.TrimLeft(t.String(), "*")
}