|
2 | 2 |
|
3 | 3 | <img align="right" width="250px" src="/resources/logo.png"> |
4 | 4 |
|
| 5 | +This library provides Go structures to marshal/unmarshal and reflect [OpenAPI Schema](https://swagger.io/resources/open-api/) documents. |
| 6 | + |
5 | 7 | [](https://github.com/swaggest/openapi-go/actions?query=branch%3Amaster+workflow%3Atest) |
6 | 8 | [](https://codecov.io/gh/swaggest/openapi-go) |
7 | 9 | [](https://pkg.go.dev/github.com/swaggest/openapi-go) |
8 | 10 |  |
9 | 11 |  |
10 | 12 |
|
11 | | -This library provides Go structures to marshal/unmarshal and reflect [OpenAPI Schema](https://swagger.io/resources/open-api/) documents. |
| 13 | +## Features |
| 14 | + |
| 15 | +* Type safe mapping of OpenAPI 3 documents with Go structures generated from schema. |
| 16 | +* Type-based reflection of Go structures to OpenAPI 3 schema using |
| 17 | +* Schema control with field tags |
| 18 | + * `json` for request bodies and responses in JSON |
| 19 | + * `query`, `path` for parameters in URL |
| 20 | + * `header`, `cookie`, `formData`, `file` for other parameters |
| 21 | + * field tags named after JSON Schema/OpenAPI 3 Schema constraints |
| 22 | +* Schema control via interfaces |
| 23 | + * [`jsonschema.Exposer`](https://pkg.go.dev/github.com/swaggest/jsonschema-go?tab=doc#Exposer) |
| 24 | + * [`jsonschema.Preparer`](https://pkg.go.dev/github.com/swaggest/jsonschema-go?tab=doc#Preparer) |
| 25 | + * [`jsonschema.RawExposer`](https://pkg.go.dev/github.com/swaggest/jsonschema-go?tab=doc#RawExposer) |
12 | 26 |
|
13 | 27 | ## Example |
14 | 28 |
|
@@ -43,213 +57,128 @@ type resp struct { |
43 | 57 |
|
44 | 58 | putOp := openapi3.Operation{} |
45 | 59 |
|
46 | | -err := reflector.SetRequest(&putOp, new(req), http.MethodPut) |
47 | | -if err != nil { |
48 | | - log.Fatal(err) |
49 | | -} |
50 | | - |
51 | | -err = reflector.SetJSONResponse(&putOp, new(resp), http.StatusOK) |
52 | | -if err != nil { |
53 | | - log.Fatal(err) |
54 | | -} |
55 | | - |
56 | | -err = reflector.SetJSONResponse(&putOp, new([]resp), http.StatusConflict) |
57 | | -if err != nil { |
58 | | - log.Fatal(err) |
59 | | -} |
| 60 | +handleError(reflector.SetRequest(&putOp, new(req), http.MethodPut)) |
| 61 | +handleError(reflector.SetJSONResponse(&putOp, new(resp), http.StatusOK)) |
| 62 | +handleError(reflector.SetJSONResponse(&putOp, new([]resp), http.StatusConflict)) |
| 63 | +handleError(reflector.Spec.AddOperation(http.MethodPut, "/things/{id}", putOp)) |
60 | 64 |
|
61 | 65 | getOp := openapi3.Operation{} |
62 | 66 |
|
63 | | -err = reflector.SetRequest(&getOp, new(req), http.MethodGet) |
64 | | -if err != nil { |
65 | | - log.Fatal(err) |
66 | | -} |
| 67 | +handleError(reflector.SetRequest(&getOp, new(req), http.MethodGet)) |
| 68 | +handleError(reflector.SetJSONResponse(&getOp, new(resp), http.StatusOK)) |
| 69 | +handleError(reflector.Spec.AddOperation(http.MethodGet, "/things/{id}", getOp)) |
67 | 70 |
|
68 | | -err = reflector.SetJSONResponse(&getOp, new(resp), http.StatusOK) |
69 | | -if err != nil { |
70 | | - log.Fatal(err) |
71 | | -} |
72 | | - |
73 | | -pathItem := reflector.Spec.Paths.MapOfPathItemValues["/things/{id}"] |
74 | | -pathItem. |
75 | | - WithSummary("Path Summary"). |
76 | | - WithDescription("Path Description") |
77 | | - |
78 | | -pathItem.WithOperation(http.MethodPut, putOp).WithOperation(http.MethodGet, getOp) |
79 | | - |
80 | | -reflector.Spec.Paths.WithMapOfPathItemValuesItem("/things/{id}", pathItem) |
81 | | - |
82 | | -schema, err := json.MarshalIndent(reflector.Spec, "", " ") |
| 71 | +schema, err := reflector.Spec.MarshalYAML() |
83 | 72 | if err != nil { |
84 | 73 | log.Fatal(err) |
85 | 74 | } |
86 | 75 |
|
87 | 76 | fmt.Println(string(schema)) |
88 | | - |
89 | | -// Output: |
90 | | -// { |
91 | | -// "openapi": "3.0.2", |
92 | | -// "info": { |
93 | | -// "title": "Things API", |
94 | | -// "description": "Put something here", |
95 | | -// "version": "1.2.3" |
96 | | -// }, |
97 | | -// "paths": { |
98 | | -// "/things/{id}": { |
99 | | -// "summary": "Path Summary", |
100 | | -// "description": "Path Description", |
101 | | -// "get": { |
102 | | -// "parameters": [ |
103 | | -// { |
104 | | -// "name": "locale", |
105 | | -// "in": "query", |
106 | | -// "schema": { |
107 | | -// "pattern": "^[a-z]{2}-[A-Z]{2}$", |
108 | | -// "type": "string" |
109 | | -// } |
110 | | -// }, |
111 | | -// { |
112 | | -// "name": "id", |
113 | | -// "in": "path", |
114 | | -// "required": true, |
115 | | -// "schema": { |
116 | | -// "type": "string", |
117 | | -// "example": "XXX-XXXXX" |
118 | | -// } |
119 | | -// } |
120 | | -// ], |
121 | | -// "responses": { |
122 | | -// "200": { |
123 | | -// "description": "OK", |
124 | | -// "content": { |
125 | | -// "application/json": { |
126 | | -// "schema": { |
127 | | -// "$ref": "#/components/schemas/Openapi3TestResp" |
128 | | -// } |
129 | | -// } |
130 | | -// } |
131 | | -// } |
132 | | -// } |
133 | | -// }, |
134 | | -// "put": { |
135 | | -// "parameters": [ |
136 | | -// { |
137 | | -// "name": "locale", |
138 | | -// "in": "query", |
139 | | -// "schema": { |
140 | | -// "pattern": "^[a-z]{2}-[A-Z]{2}$", |
141 | | -// "type": "string" |
142 | | -// } |
143 | | -// }, |
144 | | -// { |
145 | | -// "name": "id", |
146 | | -// "in": "path", |
147 | | -// "required": true, |
148 | | -// "schema": { |
149 | | -// "type": "string", |
150 | | -// "example": "XXX-XXXXX" |
151 | | -// } |
152 | | -// } |
153 | | -// ], |
154 | | -// "requestBody": { |
155 | | -// "content": { |
156 | | -// "application/json": { |
157 | | -// "schema": { |
158 | | -// "$ref": "#/components/schemas/Openapi3TestReq" |
159 | | -// } |
160 | | -// } |
161 | | -// } |
162 | | -// }, |
163 | | -// "responses": { |
164 | | -// "200": { |
165 | | -// "description": "OK", |
166 | | -// "content": { |
167 | | -// "application/json": { |
168 | | -// "schema": { |
169 | | -// "$ref": "#/components/schemas/Openapi3TestResp" |
170 | | -// } |
171 | | -// } |
172 | | -// } |
173 | | -// }, |
174 | | -// "409": { |
175 | | -// "description": "Conflict", |
176 | | -// "content": { |
177 | | -// "application/json": { |
178 | | -// "schema": { |
179 | | -// "type": "array", |
180 | | -// "items": { |
181 | | -// "$ref": "#/components/schemas/Openapi3TestResp" |
182 | | -// } |
183 | | -// } |
184 | | -// } |
185 | | -// } |
186 | | -// } |
187 | | -// } |
188 | | -// } |
189 | | -// } |
190 | | -// }, |
191 | | -// "components": { |
192 | | -// "schemas": { |
193 | | -// "Openapi3TestReq": { |
194 | | -// "type": "object", |
195 | | -// "properties": { |
196 | | -// "amount": { |
197 | | -// "minimum": 0, |
198 | | -// "type": "integer" |
199 | | -// }, |
200 | | -// "items": { |
201 | | -// "type": "array", |
202 | | -// "items": { |
203 | | -// "type": "object", |
204 | | -// "properties": { |
205 | | -// "count": { |
206 | | -// "minimum": 0, |
207 | | -// "type": "integer" |
208 | | -// }, |
209 | | -// "name": { |
210 | | -// "type": "string" |
211 | | -// } |
212 | | -// } |
213 | | -// } |
214 | | -// }, |
215 | | -// "string": { |
216 | | -// "type": "string" |
217 | | -// } |
218 | | -// } |
219 | | -// }, |
220 | | -// "Openapi3TestResp": { |
221 | | -// "type": "object", |
222 | | -// "properties": { |
223 | | -// "amount": { |
224 | | -// "minimum": 0, |
225 | | -// "type": "integer" |
226 | | -// }, |
227 | | -// "id": { |
228 | | -// "type": "string", |
229 | | -// "example": "XXX-XXXXX" |
230 | | -// }, |
231 | | -// "items": { |
232 | | -// "type": "array", |
233 | | -// "items": { |
234 | | -// "type": "object", |
235 | | -// "properties": { |
236 | | -// "count": { |
237 | | -// "minimum": 0, |
238 | | -// "type": "integer" |
239 | | -// }, |
240 | | -// "name": { |
241 | | -// "type": "string" |
242 | | -// } |
243 | | -// } |
244 | | -// } |
245 | | -// }, |
246 | | -// "updated_at": { |
247 | | -// "type": "string", |
248 | | -// "format": "date-time" |
249 | | -// } |
250 | | -// } |
251 | | -// } |
252 | | -// } |
253 | | -// } |
254 | | -// } |
| 77 | +``` |
| 78 | + |
| 79 | +Output: |
| 80 | + |
| 81 | +```yaml |
| 82 | +openapi: 3.0.2 |
| 83 | +info: |
| 84 | + description: Put something here |
| 85 | + title: Things API |
| 86 | + version: 1.2.3 |
| 87 | +paths: |
| 88 | + /things/{id}: |
| 89 | + get: |
| 90 | + parameters: |
| 91 | + - in: query |
| 92 | + name: locale |
| 93 | + schema: |
| 94 | + pattern: ^[a-z]{2}-[A-Z]{2}$ |
| 95 | + type: string |
| 96 | + - in: path |
| 97 | + name: id |
| 98 | + required: true |
| 99 | + schema: |
| 100 | + example: XXX-XXXXX |
| 101 | + type: string |
| 102 | + responses: |
| 103 | + "200": |
| 104 | + content: |
| 105 | + application/json: |
| 106 | + schema: |
| 107 | + $ref: '#/components/schemas/Openapi3TestResp' |
| 108 | + description: OK |
| 109 | + put: |
| 110 | + parameters: |
| 111 | + - in: query |
| 112 | + name: locale |
| 113 | + schema: |
| 114 | + pattern: ^[a-z]{2}-[A-Z]{2}$ |
| 115 | + type: string |
| 116 | + - in: path |
| 117 | + name: id |
| 118 | + required: true |
| 119 | + schema: |
| 120 | + example: XXX-XXXXX |
| 121 | + type: string |
| 122 | + requestBody: |
| 123 | + content: |
| 124 | + application/json: |
| 125 | + schema: |
| 126 | + $ref: '#/components/schemas/Openapi3TestReq' |
| 127 | + responses: |
| 128 | + "200": |
| 129 | + content: |
| 130 | + application/json: |
| 131 | + schema: |
| 132 | + $ref: '#/components/schemas/Openapi3TestResp' |
| 133 | + description: OK |
| 134 | + "409": |
| 135 | + content: |
| 136 | + application/json: |
| 137 | + schema: |
| 138 | + items: |
| 139 | + $ref: '#/components/schemas/Openapi3TestResp' |
| 140 | + type: array |
| 141 | + description: Conflict |
| 142 | +components: |
| 143 | + schemas: |
| 144 | + Openapi3TestReq: |
| 145 | + properties: |
| 146 | + amount: |
| 147 | + minimum: 0 |
| 148 | + type: integer |
| 149 | + items: |
| 150 | + items: |
| 151 | + properties: |
| 152 | + count: |
| 153 | + minimum: 0 |
| 154 | + type: integer |
| 155 | + name: |
| 156 | + type: string |
| 157 | + type: object |
| 158 | + type: array |
| 159 | + string: |
| 160 | + type: string |
| 161 | + type: object |
| 162 | + Openapi3TestResp: |
| 163 | + properties: |
| 164 | + amount: |
| 165 | + minimum: 0 |
| 166 | + type: integer |
| 167 | + id: |
| 168 | + example: XXX-XXXXX |
| 169 | + type: string |
| 170 | + items: |
| 171 | + items: |
| 172 | + properties: |
| 173 | + count: |
| 174 | + minimum: 0 |
| 175 | + type: integer |
| 176 | + name: |
| 177 | + type: string |
| 178 | + type: object |
| 179 | + type: array |
| 180 | + updated_at: |
| 181 | + format: date-time |
| 182 | + type: string |
| 183 | + type: object |
255 | 184 | ``` |
0 commit comments