-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathopenapi.go
More file actions
168 lines (140 loc) · 4.79 KB
/
openapi.go
File metadata and controls
168 lines (140 loc) · 4.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
package sgin
import (
"bytes"
"maps"
"regexp"
"slices"
"gopkg.in/yaml.v3"
)
const Version = "3.1.2"
var (
pathRegex = regexp.MustCompile(`([:*])([^/]+)`)
)
type (
AddOperation func(*Operation)
Requirement map[string][]string
)
type OpenAPI struct {
OpenAPI string `yaml:"openapi"`
Info *Info `yaml:"info"`
Paths map[string]*PathItem `yaml:"paths,omitempty"`
Components *Components `yaml:"components"`
Security []Requirement `yaml:"security,omitempty"`
Tags []*Tag `yaml:"tags,omitempty"`
tagMap map[string]bool
}
type Info struct {
Title string `yaml:"title"`
Version string `yaml:"version"`
}
type Tag struct {
Name string `yaml:"name"`
Description string `yaml:"description,omitempty"`
}
type PathItem struct {
Ref string `yaml:"$ref,omitempty"`
Summary string `yaml:"summary,omitempty"`
Description string `yaml:"description,omitempty"`
Get *Operation `yaml:"get,omitempty"`
Put *Operation `yaml:"put,omitempty"`
Post *Operation `yaml:"post,omitempty"`
Delete *Operation `yaml:"delete,omitempty"`
Options *Operation `yaml:"options,omitempty"`
Head *Operation `yaml:"head,omitempty"`
Patch *Operation `yaml:"patch,omitempty"`
Trace *Operation `yaml:"trace,omitempty"`
Parameters []*Param `yaml:"parameters,omitempty"`
}
type Operation struct {
Summary string `yaml:"summary,omitempty"`
Description string `yaml:"description,omitempty"`
Parameters []*Param `yaml:"parameters,omitempty"`
RequestBody *RequestBody `yaml:"requestBody,omitempty"`
Responses map[string]*ResponseBody `yaml:"responses,omitempty"`
Security []Requirement `yaml:"security,omitempty"`
Tags []string `yaml:"tags,omitempty"`
Hidden bool `yaml:"-"`
}
type Param struct {
Ref string `yaml:"$ref,omitempty"`
Name string `yaml:"name,omitempty"`
In string `yaml:"in,omitempty"` // "query", "header", "path", "cookie"
Required bool `yaml:"required,omitempty"`
Description string `yaml:"description,omitempty"`
Schema *Schema `yaml:"schema,omitempty"`
}
type RequestBody struct {
Ref string `yaml:"$ref,omitempty"`
Description string `yaml:"description,omitempty"`
Content map[string]*MediaType `yaml:"content"`
Required bool `yaml:"required,omitempty"`
}
type ResponseBody struct {
Ref string `yaml:"$ref,omitempty"`
Description string `yaml:"description,omitempty"`
Headers map[string]*Param `yaml:"headers,omitempty"`
Content map[string]*MediaType `yaml:"content,omitempty"`
}
type MediaType struct {
Schema *Schema `yaml:"schema,omitempty"`
}
type Components struct {
Schemas *Registry `yaml:"schemas,omitempty"`
SecuritySchemes map[string]*SecurityScheme `yaml:"securitySchemes,omitempty"`
}
type SecurityScheme struct {
Type string `yaml:"type"` // "http", "apiKey", "oauth2"
Description string `yaml:"description,omitempty"`
Name string `yaml:"name,omitempty"` // Header name for apiKey
In string `yaml:"in,omitempty"` // "header" for apiKey
Scheme string `yaml:"scheme,omitempty"` // "bearer" (for HTTP)
BearerFormat string `yaml:"bearerFormat,omitempty"` // "JWT" (for bearer)
}
// YAML 返回 YAML 格式的 OpenAPI 规范
func (a *OpenAPI) YAML() ([]byte, error) {
var buf bytes.Buffer
enc := yaml.NewEncoder(&buf)
enc.SetIndent(2)
if err := enc.Encode(a); err != nil {
return nil, err
}
_ = enc.Close()
return buf.Bytes(), nil
}
// Clone 返回一份深度的 Operation 副本
func (o *Operation) Clone() *Operation {
if o == nil {
return nil
}
clone := *o
clone.Parameters = slices.Clone(o.Parameters)
clone.Tags = slices.Clone(o.Tags)
clone.Responses = maps.Clone(o.Responses)
if clone.Responses == nil {
clone.Responses = map[string]*ResponseBody{}
}
return &clone
}
// APIHidden 将 Operation 标记为隐藏,使其不会出现在 OpenAPI 文档中。
func APIHidden(op *Operation) {
op.Hidden = true
}
const DocsHTML = `
<!doctype html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>API References</title>
<script src="https://unpkg.com/@stoplight/elements/web-components.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/@stoplight/elements/styles.min.css">
</head>
<body style="height: 100vh;">
<elements-api
apiDescriptionUrl="/openapi.yaml"
router="hash"
layout="sidebar"
/>
</body>
</html>
`