Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
bobgroup-go-utils
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Bob Public Utils
bobgroup-go-utils
Commits
e6979b5c
Commit
e6979b5c
authored
3 years ago
by
Johan de Klerk
Browse files
Options
Downloads
Patches
Plain Diff
docs: Better open api output
parent
515ab5b3
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
api_documentation/api_documentation.go
+134
-102
134 additions, 102 deletions
api_documentation/api_documentation.go
with
134 additions
and
102 deletions
api_documentation/api_documentation.go
+
134
−
102
View file @
e6979b5c
...
@@ -5,6 +5,7 @@ import (
...
@@ -5,6 +5,7 @@ import (
"reflect"
"reflect"
"strings"
"strings"
"gitlab.com/uafrica/go-utils/errors"
"gitlab.com/uafrica/go-utils/handler_utils"
"gitlab.com/uafrica/go-utils/handler_utils"
)
)
...
@@ -14,23 +15,34 @@ type DocPath map[string]DocMethodInfo
...
@@ -14,23 +15,34 @@ type DocPath map[string]DocMethodInfo
type
Docs
struct
{
type
Docs
struct
{
Paths
map
[
string
]
DocPath
`json:"paths"`
Paths
map
[
string
]
DocPath
`json:"paths"`
Definitions
map
[
string
]
interface
{}
Components
DocSchemas
`json:"components"`
}
}
type
DocSchemas
struct
{
Schemas
map
[
string
]
interface
{}
`json:"schemas"`
}
type
DocMethodInfo
struct
{
type
DocMethodInfo
struct
{
Summary
string
`json:"
summary
"`
Description
string
`json:"
description
"`
Tags
[]
string
`json:"tags"`
Tags
[]
string
`json:"tags"`
RequestBody
DocRequestBody
`json:"requestBody"`
Parameters
[]
DocParam
`json:"parameters,omitempty"`
Parameters
[]
DocParam
`json:"parameters,omitempty"`
Responses
map
[
string
]
DocResponseValue
`json:"responses,omitempty"`
Responses
map
[
string
]
DocResponseValue
`json:"responses,omitempty"`
}
}
type
DocRequestBody
struct
{
Description
string
`json:"description"`
Required
bool
`json:"required"`
Content
map
[
string
]
interface
{}
`json:"content"`
}
type
DocParam
struct
{
type
DocParam
struct
{
Name
string
Name
string
`json:"name"`
In
string
In
string
`json:"in"`
Type
string
Type
string
`json:"type"`
Description
string
Description
string
`json:"description"`
Schema
DocSchema
Schema
DocSchema
`json:"schema"`
}
}
type
DocSchema
struct
{
type
DocSchema
struct
{
...
@@ -39,7 +51,7 @@ type DocSchema struct {
...
@@ -39,7 +51,7 @@ type DocSchema struct {
type
DocResponseValue
struct
{
type
DocResponseValue
struct
{
Description
string
`json:"description"`
Description
string
`json:"description"`
Schema
*
DocSchemaResponse
`json:"schema,omitempty
"`
Content
map
[
string
]
interface
{}
`json:"content
"`
}
}
type
DocSchemaResponse
struct
{
type
DocSchemaResponse
struct
{
...
@@ -51,6 +63,7 @@ type DocSchemaResponse struct {
...
@@ -51,6 +63,7 @@ type DocSchemaResponse struct {
func
GetDocs
(
endpointHandlers
map
[
string
]
map
[
string
]
interface
{})
(
Docs
,
error
)
{
func
GetDocs
(
endpointHandlers
map
[
string
]
map
[
string
]
interface
{})
(
Docs
,
error
)
{
docs
:=
Docs
{
docs
:=
Docs
{
Paths
:
map
[
string
]
DocPath
{},
Paths
:
map
[
string
]
DocPath
{},
Components
:
DocSchemas
{
Schemas
:
map
[
string
]
interface
{}{}},
}
}
var
validationError
error
var
validationError
error
...
@@ -64,10 +77,10 @@ func GetDocs(endpointHandlers map[string]map[string]interface{}) (Docs, error) {
...
@@ -64,10 +77,10 @@ func GetDocs(endpointHandlers map[string]map[string]interface{}) (Docs, error) {
for
method
,
methodHandler
:=
range
methods
{
for
method
,
methodHandler
:=
range
methods
{
docMethod
:=
DocMethodInfo
{}
docMethod
:=
DocMethodInfo
{}
if
handler
,
ok
:=
methodHandler
.
(
handler_utils
.
Handler
);
!
ok
{
if
handler
,
ok
:=
methodHandler
.
(
handler_utils
.
Handler
);
!
ok
{
docMethod
.
Summary
=
"Not available"
docMethod
.
Description
=
"Not available"
}
else
{
}
else
{
//purpose
//purpose
docMethod
.
Summary
=
"Not available - see request and response structs"
docMethod
.
Description
=
"Not available - see request and response structs"
docMethod
.
Tags
=
[]
string
{
path
}
docMethod
.
Tags
=
[]
string
{
path
}
//describe parameters
//describe parameters
...
@@ -93,31 +106,47 @@ func GetDocs(endpointHandlers map[string]map[string]interface{}) (Docs, error) {
...
@@ -93,31 +106,47 @@ func GetDocs(endpointHandlers map[string]map[string]interface{}) (Docs, error) {
if
handler
.
RequestBodyType
!=
nil
{
if
handler
.
RequestBodyType
!=
nil
{
body
:=
reflect
.
New
(
handler
.
RequestBodyType
)
.
Interface
()
body
:=
reflect
.
New
(
handler
.
RequestBodyType
)
.
Interface
()
bodyTypeString
:=
getType
(
body
)
bodyTypeString
:=
getType
(
body
)
parameter
:=
DocParam
{
Name
:
"body"
,
In
:
"body"
,
docMethod
.
RequestBody
=
DocRequestBody
{
Schema
:
DocSchema
{
Ref
:
"#/definitions/"
+
bodyTypeString
},
Description
:
"Some description"
,
Required
:
true
,
Content
:
map
[
string
]
interface
{}
{
"application/json"
:
map
[
string
]
interface
{}{
"schema"
:
DocSchema
{
Ref
:
"#/components/schemas/"
+
bodyTypeString
},
},
},
}
}
docMethod
.
Parameters
=
append
(
docMethod
.
Parameters
,
parameter
)
schema
,
err
:=
StructSchema
(
handler
.
RequestBodyType
.
Field
(
0
)
.
Type
)
docs
.
Definitions
[
bodyTypeString
]
=
""
if
err
!=
nil
{
return
Docs
{},
err
}
docs
.
Components
.
Schemas
[
bodyTypeString
]
=
schema
}
}
// Response
// Response
if
handler
.
ResponseType
!=
nil
{
if
handler
.
ResponseType
!=
nil
{
responses
:=
map
[
string
]
DocResponseValue
{}
responses
:=
map
[
string
]
DocResponseValue
{}
responseBody
:=
reflect
.
New
(
handler
.
Re
questBody
Type
)
.
Interface
()
responseBody
:=
reflect
.
New
(
handler
.
Re
sponse
Type
)
.
Interface
()
responseBodyTypeString
:=
getType
(
responseBody
)
responseBodyTypeString
:=
getType
(
responseBody
)
responses
[
"200"
]
=
DocResponseValue
{
responses
[
"200"
]
=
DocResponseValue
{
Description
:
"successful operation"
,
Description
:
"Some description"
,
Schema
:
&
DocSchemaResponse
{
Content
:
map
[
string
]
interface
{}
{
Items
:
DocSchema
{
Ref
:
"#/definitions/"
+
responseBodyTypeString
},
"application/json"
:
map
[
string
]
interface
{}{
"schema"
:
DocSchema
{
Ref
:
"#/components/schemas/"
+
responseBodyTypeString
},
},
},
},
}
}
docMethod
.
Responses
=
responses
docMethod
.
Responses
=
responses
docs
.
Definitions
[
responseBodyTypeString
]
=
""
schema
,
err
:=
StructSchema
(
handler
.
ResponseType
.
Field
(
0
)
.
Type
)
if
err
!=
nil
{
return
Docs
{},
err
}
docs
.
Components
.
Schemas
[
responseBodyTypeString
]
=
schema
}
}
...
@@ -152,83 +181,86 @@ func getType(myvar interface{}) string {
...
@@ -152,83 +181,86 @@ func getType(myvar interface{}) string {
return
t
.
Name
()
return
t
.
Name
()
}
}
}
}
//
// func DocSchema(description string, t reflect.Type) (interface{}, error) {
func
StructSchema
(
t
reflect
.
Type
)
(
interface
{},
error
)
{
// if t == nil {
if
t
==
nil
{
// return nil, nil
return
nil
,
nil
// }
}
// schema := map[string]interface{}{
schema
:=
map
[
string
]
interface
{}{}
// "description": description,
// }
//
description
:=
""
// if t.Kind() == reflect.Ptr {
// schema["optional"] = true
// t = t.Elem()
if
t
.
Kind
()
==
reflect
.
Ptr
{
// }
schema
[
"optional"
]
=
true
//
t
=
t
.
Elem
()
// switch t.Kind() {
}
// case reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8, reflect.Int,
// reflect.Uint64, reflect.Uint32, reflect.Uint16, reflect.Uint8, reflect.Uint,
switch
t
.
Kind
()
{
// reflect.Float64, reflect.Float32,
case
reflect
.
Int64
,
reflect
.
Int32
,
reflect
.
Int16
,
reflect
.
Int8
,
reflect
.
Int
,
// reflect.Bool,
reflect
.
Uint64
,
reflect
.
Uint32
,
reflect
.
Uint16
,
reflect
.
Uint8
,
reflect
.
Uint
,
// reflect.String:
reflect
.
Float64
,
reflect
.
Float32
,
// schema["type"] = fmt.Sprintf("%v", t)
reflect
.
Bool
,
//
reflect
.
String
:
// case reflect.Interface:
schema
[
"type"
]
=
fmt
.
Sprintf
(
"%v"
,
t
)
// schema["type"] = "interface{}" //any value...?
//
case
reflect
.
Interface
:
// case reflect.Struct:
schema
[
"type"
]
=
"interface{}"
//any value...?
// schema["type"] = "object"
// properties := map[string]interface{}{}
case
reflect
.
Struct
:
// for i := 0; i < t.NumField(); i++ {
schema
[
"type"
]
=
"object"
// f := t.Field(i)
properties
:=
map
[
string
]
interface
{}{}
// if !f.Anonymous {
// fieldName := f.Tag.Get("json")
for
i
:=
0
;
i
<
t
.
NumField
();
i
++
{
// if fieldName == "" {
f
:=
t
.
Field
(
i
)
// fieldName = f.Name
if
!
f
.
Anonymous
{
// }
fieldName
:=
f
.
Tag
.
Get
(
"json"
)
// if fieldName == "-" {
if
fieldName
==
""
{
// continue //json does not marshal these
fieldName
=
f
.
Name
// }
}
// fieldName = strings.Replace(fieldName, ",omitempty", "", -1)
if
fieldName
==
"-"
{
//
continue
//json does not marshal these
// var err error
}
// fieldDesc := f.Tag.Get("doc")
fieldName
=
strings
.
Replace
(
fieldName
,
",omitempty"
,
""
,
-
1
)
// if fieldDesc == "" {
// fieldDesc = description + "." + fieldName
var
err
error
// }
fieldDesc
:=
f
.
Tag
.
Get
(
"doc"
)
// properties[fieldName], err = DocSchema(fieldDesc, f.Type)
if
fieldDesc
==
""
{
fieldDesc
=
description
+
"."
+
fieldName
}
properties
[
fieldName
],
err
=
StructSchema
(
f
.
Type
)
if
err
!=
nil
{
return
nil
,
errors
.
Wrapf
(
err
,
"failed to document %v.%s"
,
t
,
fieldName
)
}
}
}
schema
[
"properties"
]
=
properties
case
reflect
.
Map
:
schema
[
"type"
]
=
"map"
// keySchema, err := DocSchema("key", t.Key())
// if err != nil {
// if err != nil {
//
return nil, errors.Wrapf(err, "
failed to document %v.%s", t, fieldName
)
// return nil, errors.Wrapf(err, "
cannot make schema for %v map key", t
)
// }
// }
// }
// schema["key"] = keySchema
// }
// schema["properties"] = properties
//
// case reflect.Map:
// schema["type"] = "map"
// // 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"
// // elemSchema, err := DocSchema("items", t.Elem())
// // elemSchema, err := DocSchema("items", t.Elem())
// // if err != nil {
// if err != nil {
// // return nil, errors.Wrapf(err, "cannot make schema for %v slice elem", t)
// return nil, errors.Wrapf(err, "cannot make schema for %v map elem", t)
// // }
// // schema["items"] = elemSchema
//
// default:
// return nil, errors.Errorf("cannot generate schema for %v kind=%v", t, t.Kind())
// }
// }
//
// schema["items"] = elemSchema
// return schema, nil
case
reflect
.
Slice
:
schema
[
"type"
]
=
"array"
// 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
())
}
return
schema
,
nil
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment