Gorbunov Kirill Andreevich 95acea00d2 #2 - add swaggerset
2024-11-29 19:40:12 +03:00

184 lines
5.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package swaggerset
import (
"encoding/json"
"fmt"
"log"
"reflect"
"strings"
"github.com/getkin/kin-openapi/openapi3"
dynamicstruct "github.com/ompluscator/dynamic-struct"
)
type messages struct {
Msgs []message
}
func newMessages() *messages {
return &messages{
Msgs: make([]message, 0),
}
}
type message struct {
Type string
RequestParam interface{}
RequestBody interface{}
Response interface{}
}
func Run4() {
// Загружаем Swagger-документ
loader := openapi3.NewLoader()
doc, err := loader.LoadFromFile("swagger2.yaml")
if err != nil {
log.Fatalf("Ошибка загрузки Swagger-документа: %v", err)
}
// Пример обработки путей
for path, pathItem := range doc.Paths.Map() {
fmt.Printf("Path: %s\n", path)
// Пример обработки методов
if pathItem.Get != nil {
handleOperation("GET", pathItem.Get)
}
if pathItem.Post != nil {
handleOperation("POST", pathItem.Post)
}
}
}
// Обработка операции (GET или POST)
func handleOperation(method string, operation *openapi3.Operation) (reqParam, reqBody, rsp interface{}) {
fmt.Printf(" Method: %s\n", method)
// Обработка параметров (GET)
if len(operation.Parameters) > 0 {
paramsStruct := dynamicstruct.NewStruct()
for _, paramRef := range operation.Parameters {
param := paramRef.Value
fieldName := capitalize(param.Name)
goType := getGoType(param.Schema)
// В зависимости от того, где параметр находится (header, query, path, etc.), добавляем соответствующий тег
switch param.In {
case "query":
paramsStruct = paramsStruct.AddField(fieldName, goType, fmt.Sprintf(`json:"%s" query:"%s"`, param.Name, param.Name))
case "header":
paramsStruct = paramsStruct.AddField(fieldName, goType, fmt.Sprintf(`json:"%s" header:"%s"`, param.Name, param.Name))
default:
paramsStruct = paramsStruct.AddField(fieldName, goType, fmt.Sprintf(`json:"%s"`, param.Name))
}
}
requestStruct := paramsStruct.Build().New()
fmt.Printf(" Request (Parameters): %+v\n", requestStruct)
buf, _ := json.Marshal(requestStruct)
fmt.Printf(" Request (Parameters) JSON: %s\n", buf)
reqParam = requestStruct
}
// Обработка тела запроса (POST)
if operation.RequestBody != nil {
for _, content := range operation.RequestBody.Value.Content {
bodyFields := buildDynamicStruct(content.Schema)
bodyStruct := reflect.StructOf(bodyFields)
bodyInstance := reflect.New(bodyStruct).Interface()
fmt.Printf(" Request (Body): %+v\n", bodyInstance)
buf, _ := json.Marshal(bodyInstance)
fmt.Printf(" Request (Body) JSON: %s\n", buf)
reqBody = bodyInstance
}
}
// Обработка ответов
for status, response := range operation.Responses.Map() {
fmt.Printf(" Response Code: %s\n", status)
for _, content := range response.Value.Content {
responseFields := buildDynamicStruct(content.Schema)
responseStruct := reflect.StructOf(responseFields)
responseInstance := reflect.New(responseStruct).Interface()
fmt.Printf(" Response: %+v\n", responseInstance)
buf, _ := json.Marshal(responseInstance)
fmt.Printf(" Response JSON: %s\n", buf)
rsp = responseInstance
}
}
return
}
// Рекурсивное создание структуры из схемы с учетом $ref
func buildDynamicStruct(schema *openapi3.SchemaRef) []reflect.StructField {
var builder []reflect.StructField
fmt.Println("ref: ", schema.Ref)
if len(schema.Value.Properties) == 0 {
return builder
}
for name, prop := range schema.Value.Properties {
fieldName := capitalize(name)
if prop.Ref != "" || prop.Value.Type.Is("object") {
subBuilder := buildDynamicStruct(prop)
sfield := reflect.StructField{
Name: fieldName,
Type: reflect.StructOf(subBuilder),
Tag: reflect.StructTag(fmt.Sprintf(`json:"%s"`, name)),
}
builder = append(builder, sfield)
} else {
sfield := reflect.StructField{
Name: fieldName,
Type: reflect.TypeOf(getGoType(prop)),
Tag: reflect.StructTag(fmt.Sprintf(`json:"%s"`, name)),
}
builder = append(builder, sfield)
}
}
return builder
}
// Преобразование типа OpenAPI в тип Go
func getGoType(schema *openapi3.SchemaRef) interface{} {
switch {
case schema.Value.Type.Is("string"):
return ""
case schema.Value.Type.Is("integer"):
return 0
case schema.Value.Type.Is("boolean"):
return false
case schema.Value.Type.Is("array"):
return []interface{}{}
case schema.Value.Type.Is("object"):
return buildDynamicStruct(schema)
default:
return nil
}
}
func capitalize(fieldName string) string {
// Заменяем точки на подчеркивания для унификации
fieldName = strings.ReplaceAll(fieldName, ".", "_")
// Разделяем строку по подчеркиваниям
parts := strings.Split(fieldName, "_")
if len(parts) == 1 {
return strings.ToUpper(fieldName[:1]) + fieldName[1:]
}
// Обрабатываем каждый фрагмент
for i := 0; i < len(parts); i++ {
// Капитализируем первые буквы всех частей, кроме первой
parts[i] = strings.Title(parts[i])
}
// Собираем строку обратно, соединяя части без подчеркиваний
return strings.Join(parts, "")
}