Skip to content

Commit 698d96a

Browse files
authored
Merge pull request #179 from kaleido-io/revert-open-api-public-func-change
revert changes on the public functions of OpenAPIHandlerFactory struct
2 parents 19e0a20 + ebfb384 commit 698d96a

File tree

5 files changed

+94
-97
lines changed

5 files changed

+94
-97
lines changed

pkg/ffapi/apiserver.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ func (as *apiServer[T]) createMuxRouter(ctx context.Context) (*mux.Router, error
285285
hf := as.handlerFactory()
286286

287287
as.oah = &OpenAPIHandlerFactory{
288-
BaseSwaggerGenOptions: BaseSwaggerGenOptions{
288+
BaseSwaggerGenOptions: SwaggerGenOptions{
289289
Title: as.Description,
290290
Version: "1.0",
291291
PanicOnMissingDescription: as.PanicOnMissingDescription,
@@ -335,10 +335,10 @@ func (as *apiServer[T]) createMuxRouter(ctx context.Context) (*mux.Router, error
335335
}
336336
}
337337

338-
r.HandleFunc(`/api/swagger.yaml`, hf.APIWrapper(as.oah.OpenAPIHandler(fmt.Sprintf(`/api/%s`, defaultAPIVersion), OpenAPIFormatYAML, defaultAPIVersionObject)))
339-
r.HandleFunc(`/api/swagger.json`, hf.APIWrapper(as.oah.OpenAPIHandler(fmt.Sprintf(`/api/%s`, defaultAPIVersion), OpenAPIFormatJSON, defaultAPIVersionObject)))
340-
r.HandleFunc(`/api/openapi.yaml`, hf.APIWrapper(as.oah.OpenAPIHandler(fmt.Sprintf(`/api/%s`, defaultAPIVersion), OpenAPIFormatYAML, defaultAPIVersionObject)))
341-
r.HandleFunc(`/api/openapi.json`, hf.APIWrapper(as.oah.OpenAPIHandler(fmt.Sprintf(`/api/%s`, defaultAPIVersion), OpenAPIFormatJSON, defaultAPIVersionObject)))
338+
r.HandleFunc(`/api/swagger.yaml`, hf.APIWrapper(as.oah.OpenAPIHandlerVersioned(fmt.Sprintf(`/api/%s`, defaultAPIVersion), OpenAPIFormatYAML, defaultAPIVersionObject)))
339+
r.HandleFunc(`/api/swagger.json`, hf.APIWrapper(as.oah.OpenAPIHandlerVersioned(fmt.Sprintf(`/api/%s`, defaultAPIVersion), OpenAPIFormatJSON, defaultAPIVersionObject)))
340+
r.HandleFunc(`/api/openapi.yaml`, hf.APIWrapper(as.oah.OpenAPIHandlerVersioned(fmt.Sprintf(`/api/%s`, defaultAPIVersion), OpenAPIFormatYAML, defaultAPIVersionObject)))
341+
r.HandleFunc(`/api/openapi.json`, hf.APIWrapper(as.oah.OpenAPIHandlerVersioned(fmt.Sprintf(`/api/%s`, defaultAPIVersion), OpenAPIFormatJSON, defaultAPIVersionObject)))
342342
r.HandleFunc(`/api`, hf.APIWrapper(as.oah.SwaggerUIHandler(`/api/openapi.yaml`)))
343343
r.HandleFunc(`/favicon{any:.*}.png`, favIconsHandler(as.FavIcon16, as.FavIcon32))
344344

@@ -371,8 +371,8 @@ func (as *apiServer[T]) addRoutesForVersion(ctx context.Context, r *mux.Router,
371371
}
372372

373373
// adding open api documentation for this api version
374-
r.HandleFunc(fmt.Sprintf("/api/%s/openapi.yaml", apiVersion), hf.APIWrapper(as.oah.OpenAPIHandler(fmt.Sprintf("/api/%s", apiVersion), OpenAPIFormatYAML, apiVersionObject)))
375-
r.HandleFunc(fmt.Sprintf("/api/%s/openapi.json", apiVersion), hf.APIWrapper(as.oah.OpenAPIHandler(fmt.Sprintf("/api/%s", apiVersion), OpenAPIFormatJSON, apiVersionObject)))
374+
r.HandleFunc(fmt.Sprintf("/api/%s/openapi.yaml", apiVersion), hf.APIWrapper(as.oah.OpenAPIHandlerVersioned(fmt.Sprintf("/api/%s", apiVersion), OpenAPIFormatYAML, apiVersionObject)))
375+
r.HandleFunc(fmt.Sprintf("/api/%s/openapi.json", apiVersion), hf.APIWrapper(as.oah.OpenAPIHandlerVersioned(fmt.Sprintf("/api/%s", apiVersion), OpenAPIFormatJSON, apiVersionObject)))
376376

377377
return nil
378378
}

pkg/ffapi/openapi3.go

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,27 @@ import (
3636
)
3737

3838
type SwaggerGenOptions struct {
39+
// ---------- options that applies to all API versions ----------
40+
41+
// attributes of openapi3.Info
42+
Title string
43+
Version string
44+
Description string
45+
46+
// descriptions for the route parameters are parsed from the ffstruct tags
47+
// when set this flag to true, if a description is not found, the generator will panic
48+
// this is useful to ensure that all fields are documented
49+
PanicOnMissingDescription bool
50+
51+
SupportFieldRedaction bool
52+
DefaultRequestTimeout time.Duration
53+
54+
// ----------- API version specific options ------------
3955
// options to generate the base URL
4056
BaseURL string
4157
BaseURLVariables map[string]BaseURLVariable
4258

43-
BaseSwaggerGenOptions
44-
4559
// options of controlling query parameters values
46-
4760
APIMaxFilterSkip uint
4861
APIDefaultFilterLimit string
4962
APIMaxFilterLimit uint
@@ -56,22 +69,6 @@ type SwaggerGenOptions struct {
5669
ExternalDocs *openapi3.ExternalDocs
5770
}
5871

59-
type BaseSwaggerGenOptions struct { // options that applies to all API versions
60-
61-
// attributes of openapi3.Info
62-
Title string
63-
Version string
64-
Description string
65-
66-
// descriptions for the route parameters are parsed from the ffstruct tags
67-
// when set this flag to true, if a description is not found, the generator will panic
68-
// this is useful to ensure that all fields are documented
69-
PanicOnMissingDescription bool
70-
71-
SupportFieldRedaction bool
72-
DefaultRequestTimeout time.Duration
73-
}
74-
7572
type BaseURLVariable struct {
7673
Default string
7774
Description string
@@ -320,9 +317,7 @@ func (sg *SwaggerGen) addURLEncodedFormInput(ctx context.Context, op *openapi3.O
320317
func CheckObjectDocumented(example interface{}) {
321318
(&SwaggerGen{
322319
options: &SwaggerGenOptions{
323-
BaseSwaggerGenOptions: BaseSwaggerGenOptions{
324-
PanicOnMissingDescription: true,
325-
},
320+
PanicOnMissingDescription: true,
326321
},
327322
}).Generate(context.Background(), []*Route{{
328323
Name: "doctest",

pkg/ffapi/openapi3_test.go

Lines changed: 35 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -196,12 +196,10 @@ type TestNonTaggedType struct {
196196

197197
func TestOpenAPI3SwaggerGen(t *testing.T) {
198198
doc := NewSwaggerGen(&SwaggerGenOptions{
199-
BaseSwaggerGenOptions: BaseSwaggerGenOptions{
200-
Title: "UnitTest",
201-
Version: "1.0",
202-
SupportFieldRedaction: true,
203-
},
204-
BaseURL: "http://localhost:12345/api/v1",
199+
Title: "UnitTest",
200+
Version: "1.0",
201+
SupportFieldRedaction: true,
202+
BaseURL: "http://localhost:12345/api/v1",
205203
RouteCustomizations: func(ctx context.Context, sg *SwaggerGen, route *Route, op *openapi3.Operation) {
206204
sg.AddParam(ctx, op, "header", "x-my-param", "thing", "stuff", ExampleDesc, false)
207205
},
@@ -233,10 +231,8 @@ func TestBadCustomInputSchemaFail(t *testing.T) {
233231
}
234232
assert.Panics(t, func() {
235233
_ = NewSwaggerGen(&SwaggerGenOptions{
236-
BaseSwaggerGenOptions: BaseSwaggerGenOptions{
237-
Title: "UnitTest",
238-
Version: "1.0",
239-
},
234+
Title: "UnitTest",
235+
Version: "1.0",
240236
BaseURL: "http://localhost:12345/api/v1",
241237
}).Generate(context.Background(), routes)
242238
})
@@ -257,10 +253,8 @@ func TestBadCustomOutputSchemaFail(t *testing.T) {
257253
}
258254
assert.Panics(t, func() {
259255
_ = NewSwaggerGen(&SwaggerGenOptions{
260-
BaseSwaggerGenOptions: BaseSwaggerGenOptions{
261-
Title: "UnitTest",
262-
Version: "1.0",
263-
},
256+
Title: "UnitTest",
257+
Version: "1.0",
264258
BaseURL: "http://localhost:12345/api/v1",
265259
}).Generate(context.Background(), routes)
266260
})
@@ -272,11 +266,8 @@ func TestDuplicateOperationIDCheck(t *testing.T) {
272266
}
273267
assert.PanicsWithValue(t, "Duplicate/invalid name (used as operation ID in swagger): op1", func() {
274268
_ = NewSwaggerGen(&SwaggerGenOptions{
275-
BaseSwaggerGenOptions: BaseSwaggerGenOptions{
276-
Title: "UnitTest",
277-
Version: "1.0",
278-
},
279-
BaseURL: "http://localhost:12345/api/v1",
269+
Title: "UnitTest",
270+
Version: "1.0",
280271
}).Generate(context.Background(), routes)
281272
})
282273
}
@@ -292,10 +283,10 @@ func TestWildcards(t *testing.T) {
292283
},
293284
}
294285
swagger := NewSwaggerGen(&SwaggerGenOptions{
295-
BaseSwaggerGenOptions: BaseSwaggerGenOptions{
296-
Title: "UnitTest",
297-
Version: "1.0",
298-
},
286+
287+
Title: "UnitTest",
288+
Version: "1.0",
289+
299290
BaseURL: "http://localhost:12345/api/v1",
300291
}).Generate(context.Background(), routes)
301292
assert.NotNil(t, swagger.Paths.Find("/namespaces/{ns}/example1/{id}"))
@@ -314,10 +305,8 @@ func TestFFExcludeTag(t *testing.T) {
314305
},
315306
}
316307
swagger := NewSwaggerGen(&SwaggerGenOptions{
317-
BaseSwaggerGenOptions: BaseSwaggerGenOptions{
318-
Title: "UnitTest",
319-
Version: "1.0",
320-
},
308+
Title: "UnitTest",
309+
Version: "1.0",
321310
BaseURL: "http://localhost:12345/api/v1",
322311
}).Generate(context.Background(), routes)
323312
assert.NotNil(t, swagger.Paths.Find("/namespaces/{ns}/example1/test").Post.RequestBody.Value)
@@ -353,10 +342,9 @@ func TestCustomResponseRefs(t *testing.T) {
353342
},
354343
}
355344
swagger := NewSwaggerGen(&SwaggerGenOptions{
356-
BaseSwaggerGenOptions: BaseSwaggerGenOptions{
357-
Title: "UnitTest",
358-
Version: "1.0",
359-
},
345+
Title: "UnitTest",
346+
Version: "1.0",
347+
360348
BaseURL: "http://localhost:12345/api/v1",
361349
}).Generate(context.Background(), routes)
362350
assert.Nil(t, swagger.Paths.Find("/test").Get.RequestBody)
@@ -381,12 +369,10 @@ func TestPanicOnMissingDescription(t *testing.T) {
381369
}
382370
assert.PanicsWithValue(t, "invalid schema: FF00158: Field description missing for 'TestInOutType.conditional' on route 'PostPanicOnMissingDescription'", func() {
383371
_ = NewSwaggerGen(&SwaggerGenOptions{
384-
BaseSwaggerGenOptions: BaseSwaggerGenOptions{
385-
Title: "UnitTest",
386-
Version: "1.0",
387-
PanicOnMissingDescription: true,
388-
},
389-
BaseURL: "http://localhost:12345/api/v1",
372+
Title: "UnitTest",
373+
Version: "1.0",
374+
PanicOnMissingDescription: true,
375+
BaseURL: "http://localhost:12345/api/v1",
390376
}).Generate(context.Background(), routes)
391377
})
392378
}
@@ -404,12 +390,10 @@ func TestPanicOnMissingFFStructTag(t *testing.T) {
404390
}
405391
assert.PanicsWithValue(t, "invalid schema: FF00160: ffstruct tag is missing for 'noFFStructTag' on route 'GetPanicOnMissingFFStructTag'", func() {
406392
_ = NewSwaggerGen(&SwaggerGenOptions{
407-
BaseSwaggerGenOptions: BaseSwaggerGenOptions{
408-
Title: "UnitTest",
409-
Version: "1.0",
410-
PanicOnMissingDescription: true,
411-
},
412-
BaseURL: "http://localhost:12345/api/v1",
393+
Title: "UnitTest",
394+
Version: "1.0",
395+
PanicOnMissingDescription: true,
396+
BaseURL: "http://localhost:12345/api/v1",
413397
}).Generate(context.Background(), routes)
414398
})
415399
}
@@ -426,12 +410,10 @@ func TestPanicOnMissingRouteDescription(t *testing.T) {
426410
}
427411
assert.PanicsWithValue(t, "FF00159: API route description missing for route 'GetPanicOnMissingRouteDescription'", func() {
428412
_ = NewSwaggerGen(&SwaggerGenOptions{
429-
BaseSwaggerGenOptions: BaseSwaggerGenOptions{
430-
Title: "UnitTest",
431-
Version: "1.0",
432-
PanicOnMissingDescription: true,
433-
},
434-
BaseURL: "http://localhost:12345/api/v1",
413+
Title: "UnitTest",
414+
Version: "1.0",
415+
PanicOnMissingDescription: true,
416+
BaseURL: "http://localhost:12345/api/v1",
435417
}).Generate(context.Background(), routes)
436418
})
437419
}
@@ -449,10 +431,8 @@ func TestPreTranslatedRouteDescription(t *testing.T) {
449431
},
450432
}
451433
swagger := NewSwaggerGen(&SwaggerGenOptions{
452-
BaseSwaggerGenOptions: BaseSwaggerGenOptions{
453-
Title: "UnitTest",
454-
Version: "1.0",
455-
},
434+
Title: "UnitTest",
435+
Version: "1.0",
456436
BaseURL: "http://localhost:12345/api/v1",
457437
}).Generate(context.Background(), routes)
458438
assert.NotNil(t, swagger.Paths.Find("/namespaces/{ns}/example1/test").Post.RequestBody.Value)
@@ -464,10 +444,8 @@ func TestPreTranslatedRouteDescription(t *testing.T) {
464444

465445
func TestBaseURLVariables(t *testing.T) {
466446
doc := NewSwaggerGen(&SwaggerGenOptions{
467-
BaseSwaggerGenOptions: BaseSwaggerGenOptions{
468-
Title: "UnitTest",
469-
Version: "1.0",
470-
},
447+
Title: "UnitTest",
448+
Version: "1.0",
471449
BaseURL: "http://localhost:12345/api/v1/{param}",
472450
BaseURLVariables: map[string]BaseURLVariable{
473451
"param": {

pkg/ffapi/openapihandler.go

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ const (
3333
)
3434

3535
type OpenAPIHandlerFactory struct {
36-
BaseSwaggerGenOptions BaseSwaggerGenOptions
36+
BaseSwaggerGenOptions SwaggerGenOptions
3737
StaticPublicURL string
3838
DynamicPublicURLHeader string
3939
DynamicPublicURLBuilder func(req *http.Request) string
@@ -106,14 +106,38 @@ func (ohf *OpenAPIHandlerFactory) getPublicURL(req *http.Request, relativePath s
106106
return publicURL
107107
}
108108

109-
func (ohf *OpenAPIHandlerFactory) OpenAPIHandler(apiPath string, format OpenAPIFormat, apiVersionObject *APIVersion) HandlerFunction {
109+
func (ohf *OpenAPIHandlerFactory) OpenAPIHandler(apiPath string, format OpenAPIFormat, routes []*Route) HandlerFunction {
110110
return func(res http.ResponseWriter, req *http.Request) (int, error) {
111-
doc := NewSwaggerGen(&SwaggerGenOptions{
112-
BaseSwaggerGenOptions: ohf.BaseSwaggerGenOptions,
113-
BaseURL: ohf.getPublicURL(req, apiPath),
114-
Tags: apiVersionObject.Tags,
115-
ExternalDocs: apiVersionObject.ExternalDocs,
116-
}).Generate(req.Context(), apiVersionObject.Routes)
111+
options := ohf.BaseSwaggerGenOptions
112+
113+
// adding/overriding non-based options
114+
options.BaseURL = ohf.getPublicURL(req, apiPath)
115+
116+
doc := NewSwaggerGen(&options).Generate(req.Context(), routes)
117+
if format == OpenAPIFormatJSON {
118+
res.Header().Add("Content-Type", "application/json")
119+
b, _ := json.Marshal(&doc)
120+
_, _ = res.Write(b)
121+
} else {
122+
res.Header().Add("Content-Type", "application/x-yaml")
123+
b, _ := yaml.Marshal(&doc)
124+
_, _ = res.Write(b)
125+
}
126+
return 200, nil
127+
}
128+
}
129+
130+
func (ohf *OpenAPIHandlerFactory) OpenAPIHandlerVersioned(apiPath string, format OpenAPIFormat, apiVersionObject *APIVersion) HandlerFunction {
131+
return func(res http.ResponseWriter, req *http.Request) (int, error) {
132+
options := ohf.BaseSwaggerGenOptions
133+
134+
// adding/overriding non-based options
135+
options.BaseURL = ohf.getPublicURL(req, apiPath)
136+
// version specific options must be explicitly provided
137+
options.Tags = apiVersionObject.Tags
138+
options.ExternalDocs = apiVersionObject.ExternalDocs
139+
140+
doc := NewSwaggerGen(&options).Generate(req.Context(), apiVersionObject.Routes)
117141
if format == OpenAPIFormatJSON {
118142
res.Header().Add("Content-Type", "application/json")
119143
b, _ := json.Marshal(&doc)

pkg/ffapi/openapihandler_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import (
2929

3030
func TestOpenAPI3SwaggerUI(t *testing.T) {
3131
oaf := &OpenAPIHandlerFactory{
32-
BaseSwaggerGenOptions: BaseSwaggerGenOptions{},
32+
BaseSwaggerGenOptions: SwaggerGenOptions{},
3333
StaticPublicURL: "http://localhost:12345/basepath",
3434
}
3535
testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
@@ -51,7 +51,7 @@ func TestOpenAPI3SwaggerUI(t *testing.T) {
5151

5252
func TestOpenAPI3SwaggerUIDynamicPublicURLHeader(t *testing.T) {
5353
oaf := &OpenAPIHandlerFactory{
54-
BaseSwaggerGenOptions: BaseSwaggerGenOptions{},
54+
BaseSwaggerGenOptions: SwaggerGenOptions{},
5555
DynamicPublicURLHeader: "X-External-URL",
5656
}
5757
testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
@@ -75,7 +75,7 @@ func TestOpenAPI3SwaggerUIDynamicPublicURLHeader(t *testing.T) {
7575

7676
func TestOpenAPI3SwaggerUIDynamicPublicURL(t *testing.T) {
7777
oaf := &OpenAPIHandlerFactory{
78-
BaseSwaggerGenOptions: BaseSwaggerGenOptions{},
78+
BaseSwaggerGenOptions: SwaggerGenOptions{},
7979
DynamicPublicURLBuilder: func(req *http.Request) string {
8080
return fmt.Sprintf("https://%s/", req.Header.Get("X-Forwarded-Host"))
8181
},

0 commit comments

Comments
 (0)