From 27579923128703b7a7713b1dc5f4a0441a3ed86a Mon Sep 17 00:00:00 2001 From: Johan de Klerk <jdeklerk00@gmail.com> Date: Tue, 10 May 2022 13:58:23 +0200 Subject: [PATCH] Docs cleanup --- api_documentation/api_documentation.go | 179 +++++++++++++------------ 1 file changed, 90 insertions(+), 89 deletions(-) diff --git a/api_documentation/api_documentation.go b/api_documentation/api_documentation.go index 8dd3497..44e1528 100644 --- a/api_documentation/api_documentation.go +++ b/api_documentation/api_documentation.go @@ -46,7 +46,7 @@ type DocParam struct { Name string `json:"name"` In string `json:"in"` Description string `json:"description"` - Required bool `json:"required,omitempty"` + Required bool `json:"required,omitempty"` Schema interface{} `json:"schema"` } @@ -84,60 +84,22 @@ func GetDocs(endpointHandlers map[string]map[string]interface{}, corePath string if handler, ok := methodHandler.(handler_utils.Handler); !ok { docMethod.Description = "Not available" } else { - // purpose + // Meta data functionName := GetFunctionName(handler.FuncValue.Interface()) docMethod.Description = functionDocs[functionName] docMethod.Tags = []string{path} - // describe parameters - docMethod.Parameters = []DocParam{} - for i := 0; i < handler.RequestParamsType.NumField(); i++ { - f := handler.RequestParamsType.Field(i) - - shouldAddDoc := f.Tag.Get("doc") - if shouldAddDoc == "-" { - continue - } - - name := f.Tag.Get("json") - if name == "" { - name = f.Name - } - name = strings.Replace(name, ",omitempty", "", -1) - - schema, err := StructSchema(f.Type) - if err != nil { - return Docs{}, err - } - - parameter := DocParam{ - Name: name, - In: "query", - Description: f.Tag.Get("doc"), - Schema: schema, - } - - if f.Tag.Get("doc_required") == "true" { - parameter.Required = true - } - - docMethod.Parameters = append(docMethod.Parameters, parameter) + // Parameters + docParameters, err := FillParameters(handler) + if err != nil { + return Docs{}, err } + docMethod.Parameters = docParameters - // Request + // Request body if handler.RequestBodyType != nil { - body := reflect.New(handler.RequestBodyType).Interface() - bodyTypeString := getType(body) - - docMethod.RequestBody = &DocRequestBody{ - Description: functionDocs[bodyTypeString], - Required: true, - Content: map[string]interface{}{ - "application/json": map[string]interface{}{ - "schema": DocSchema{Ref: "#/components/schemas/" + bodyTypeString}, - }, - }, - } + bodyTypeString, requestBody := GetRequestBody(handler, functionDocs) + docMethod.RequestBody = &requestBody if handler.RequestBodyType.Kind() == reflect.Struct && handler.RequestBodyType.NumField() > 0 { schema, err := StructSchema(handler.RequestBodyType.Field(0).Type) @@ -150,25 +112,8 @@ func GetDocs(endpointHandlers map[string]map[string]interface{}, corePath string // Response if handler.ResponseType != nil { - responses := map[string]DocResponseValue{} - responseBody := reflect.New(handler.ResponseType).Interface() - responseBodyTypeString := getType(responseBody) - - response := DocResponseValue{ - Description: "", - } - responses["200"] = response - - if responseBodyTypeString != "" { - response.Content = &map[string]interface{}{ - "application/json": map[string]interface{}{ - "schema": DocSchema{Ref: "#/components/schemas/" + responseBodyTypeString}, - }, - } - } - - docMethod.Responses = &responses - + response, responseBodyTypeString := GetResponse(handler) + docMethod.Responses = &response if handler.ResponseType.Kind() == reflect.Struct && handler.ResponseType.NumField() > 0 { schema, err := StructSchema(handler.ResponseType.Field(0).Type) if err != nil { @@ -187,6 +132,84 @@ func GetDocs(endpointHandlers map[string]map[string]interface{}, corePath string return docs, nil } +func FillParameters(handler handler_utils.Handler) ([]DocParam, error) { + + docParameters := []DocParam{} + for i := 0; i < handler.RequestParamsType.NumField(); i++ { + structField := handler.RequestParamsType.Field(i) + + shouldAddDoc := structField.Tag.Get("doc") + if shouldAddDoc == "-" { + continue + } + + schema, err := StructSchema(structField.Type) + if err != nil { + return nil, err + } + + parameter := DocParam{ + Name: StructFieldName(structField), + In: "query", + Description: structField.Tag.Get("doc"), + Schema: schema, + } + + if structField.Tag.Get("doc_required") == "true" { + parameter.Required = true + } + + docParameters = append(docParameters, parameter) + } + + return docParameters, nil +} + +func GetRequestBody(handler handler_utils.Handler, functionDocs map[string]string) (string, DocRequestBody) { + body := reflect.New(handler.RequestBodyType).Interface() + bodyTypeString := getType(body) + + requestBody := DocRequestBody{ + Description: functionDocs[bodyTypeString], + Required: true, + Content: map[string]interface{}{ + "application/json": map[string]interface{}{ + "schema": DocSchema{Ref: "#/components/schemas/" + bodyTypeString}, + }, + }, + } + return bodyTypeString, requestBody +} + +func GetResponse(handler handler_utils.Handler) (map[string]DocResponseValue, string) { + responses := map[string]DocResponseValue{} + responseBody := reflect.New(handler.ResponseType).Interface() + responseBodyTypeString := getType(responseBody) + + response := DocResponseValue{} + if responseBodyTypeString != "" { + response.Content = &map[string]interface{}{ + "application/json": map[string]interface{}{ + "schema": DocSchema{Ref: "#/components/schemas/" + responseBodyTypeString}, + }, + } + } + + responses["200"] = response + + return responses, responseBodyTypeString +} + +func StructFieldName(structField reflect.StructField) string { + name := structField.Tag.Get("json") + if name == "" { + name = structField.Name + } + + name = strings.Replace(name, ",omitempty", "", -1) + return name +} + func getType(myvar interface{}) string { if t := reflect.TypeOf(myvar); t.Kind() == reflect.Ptr { return t.Elem().Name() @@ -264,26 +287,9 @@ func StructSchema(t reflect.Type) (interface{}, error) { case reflect.Map: schema["type"] = "object" - // keySchema, err := DocSchema("key", t.Key()) - // if err != nil { - // return nil, errors.Wrapf(err, "cannot make schema for %v map key", t) - // } - // schema["key"] = keySchema - // // elemSchema, err := DocSchema("items", t.Elem()) - // if err != nil { - // return nil, errors.Wrapf(err, "cannot make schema for %v map elem", t) - // } - // schema["items"] = elemSchema - case reflect.Slice: schema["type"] = "array" schema["items"] = t.Elem() - // elemSchema, err := DocSchema("items", t.Elem()) - // if err != nil { - // return nil, errors.Wrapf(err, "cannot make schema for %v slice elem", t) - // } - // schema["items"] = elemSchema - default: return nil, errors.Errorf("cannot generate schema for %v kind=%v", t, t.Kind()) } @@ -317,11 +323,6 @@ func GetStructDocs(corePath string) map[string]string { doc := strings.ReplaceAll(objectTypes.Doc, objectTypes.Name, "") docs[objectTypes.Name] = doc } - // - // for _, v := range p.Vars { - // fmt.Println("type", v.Names) - // fmt.Println("docs:", v.Doc) - // } for _, function := range p.Funcs { doc := strings.ReplaceAll(function.Doc, function.Name, "") -- GitLab