Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions pkg/ffapi/openapi3.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ func (sg *SwaggerGen) Generate(ctx context.Context, routes []*Route) *openapi3.T
}
opIDs := make(map[string]bool)
for _, route := range routes {
// Skip routes that are excluded from OpenAPI generation
if route.ExcludeFromOpenAPI {
continue
}
if route.Name == "" || opIDs[route.Name] {
log.Panicf("Duplicate/invalid name (used as operation ID in swagger): %s", route.Name)
}
Expand Down
60 changes: 60 additions & 0 deletions pkg/ffapi/openapi3_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -518,3 +518,63 @@ func TestCheckObjectDocumented(t *testing.T) {
}()
CheckObjectDocumented(&Undocumented{})
}

func TestExcludeFromOpenAPI(t *testing.T) {
routes := []*Route{
{
Name: "IncludedRoute",
Path: "included",
Method: http.MethodGet,
Description: ExampleDesc,
JSONInputValue: func() interface{} { return &TestStruct1{} },
JSONOutputValue: func() interface{} { return &TestStruct1{} },
JSONOutputCodes: []int{http.StatusOK},
ExcludeFromOpenAPI: false,
},
{
Name: "ExcludedRoute",
Path: "excluded",
Method: http.MethodPost,
Description: ExampleDesc,
JSONInputValue: func() interface{} { return &TestStruct1{} },
JSONOutputValue: func() interface{} { return &TestStruct1{} },
JSONOutputCodes: []int{http.StatusOK},
ExcludeFromOpenAPI: true,
},
{
Name: "AnotherIncludedRoute",
Path: "another-included",
Method: http.MethodPut,
Description: ExampleDesc,
JSONInputValue: func() interface{} { return &TestStruct1{} },
JSONOutputValue: func() interface{} { return &TestStruct1{} },
JSONOutputCodes: []int{http.StatusOK},
ExcludeFromOpenAPI: false,
},
}

doc := NewSwaggerGen(&SwaggerGenOptions{
Title: "ExcludeFromOpenAPITest",
Version: "1.0",
BaseURL: "http://localhost:12345/api/v1",
}).Generate(context.Background(), routes)

assert.NotNil(t, doc.Paths)

// Check that included routes are present
includedPath := doc.Paths.Find("/included")
assert.NotNil(t, includedPath)
assert.NotNil(t, includedPath.Get) // GET method should be present

anotherIncludedPath := doc.Paths.Find("/another-included")
assert.NotNil(t, anotherIncludedPath)
assert.NotNil(t, anotherIncludedPath.Put) // PUT method should be present

// Check that excluded route is not present
excludedPath := doc.Paths.Find("/excluded")
assert.Nil(t, excludedPath) // Should be nil because route was excluded

// Verify the document is valid
err := doc.Validate(context.Background())
assert.NoError(t, err)
}
4 changes: 2 additions & 2 deletions pkg/ffapi/openapihandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ type OpenAPIHandlerFactory struct {
DynamicPublicURLBuilder func(req *http.Request) string
}

func swaggerUIHTML(swaggerURL string) []byte {
func SwaggerUIHTML(swaggerURL string) []byte {
return []byte(fmt.Sprintf(
`<!DOCTYPE html>
<html lang="en">
Expand Down Expand Up @@ -150,7 +150,7 @@ func (ohf *OpenAPIHandlerFactory) OpenAPIHandlerVersioned(apiPath string, format
func (ohf *OpenAPIHandlerFactory) SwaggerUIHandler(openAPIPath string) HandlerFunction {
return func(res http.ResponseWriter, req *http.Request) (status int, err error) {
res.Header().Add("Content-Type", "text/html")
_, _ = res.Write(swaggerUIHTML(ohf.getPublicURL(req, openAPIPath)))
_, _ = res.Write(SwaggerUIHTML(ohf.getPublicURL(req, openAPIPath)))
return 200, nil
}
}
2 changes: 2 additions & 0 deletions pkg/ffapi/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ type Route struct {
Deprecated bool
// Tag a category identifier for this route in the generated OpenAPI spec
Tag string
// ExcludeFromOpenAPI if true, this route will not be included in the generated OpenAPI specification
ExcludeFromOpenAPI bool
// Extensions allows extension of the route struct by individual microservices
Extensions interface{}
}
Expand Down