Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Default OpenAPI handler public #83

Merged
merged 2 commits into from
Mar 20, 2024
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
1 change: 0 additions & 1 deletion examples/full-app-gourmet/views/views.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,4 @@ func (rs Ressource) Routes(s *fuego.Server) {

fuego.Post(adminRoutes, "/ingredients/new", rs.adminCreateIngredient)
fuego.Get(adminRoutes, "/users", rs.adminRecipes)

}
2 changes: 1 addition & 1 deletion openapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func registerOpenAPIRoutes(s *Server, jsonSpec []byte) {
_, _ = w.Write(jsonSpec)
})

Handle(s, s.OpenAPIConfig.SwaggerUrl+"/", s.UIHandler(s.OpenAPIConfig.JsonUrl))
Handle(s, s.OpenAPIConfig.SwaggerUrl+"/", s.OpenAPIConfig.UIHandler(s.OpenAPIConfig.JsonUrl))

slog.Info(fmt.Sprintf("JSON spec: http://%s%s", s.Server.Addr, s.OpenAPIConfig.JsonUrl))
slog.Info(fmt.Sprintf("OpenAPI UI: http://%s%s/index.html", s.Server.Addr, s.OpenAPIConfig.SwaggerUrl))
Expand Down
2 changes: 1 addition & 1 deletion openapi_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"net/http"
)

func defaultOpenAPIHandler(specURL string) http.Handler {
func DefaultOpenAPIHandler(specURL string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
_, _ = w.Write([]byte(`<!doctype html>
Expand Down
50 changes: 50 additions & 0 deletions openapi_handler_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package fuego

import (
"net/http"
"net/http/httptest"
"testing"

"github.com/stretchr/testify/require"
)

func TestDefaultOpenAPIHandler(t *testing.T) {
t.Run("works with DefaultOpenAPIHandler", func(t *testing.T) {
s := NewServer()

s.OutputOpenAPISpec()

require.NotNil(t, s.OpenAPIConfig.UIHandler)

w := httptest.NewRecorder()
r := httptest.NewRequest("GET", "/swagger/index.html", nil)

s.Mux.ServeHTTP(w, r)

require.Equal(t, 200, w.Code)
require.Contains(t, w.Body.String(), "OpenAPI specification")
require.Equal(t, "", w.Header().Get("X-Test-Response"))
})

t.Run("wrap DefaultOpenAPIHandler behind a middleware", func(t *testing.T) {
s := NewServer(
WithOpenAPIConfig(OpenAPIConfig{
UIHandler: func(specURL string) http.Handler {
return dummyMiddleware(DefaultOpenAPIHandler(specURL))
},
}),
)
s.OutputOpenAPISpec()

require.NotNil(t, s.OpenAPIConfig.UIHandler)

w := httptest.NewRecorder()
r := httptest.NewRequest("GET", "/swagger/index.html", nil)

s.Mux.ServeHTTP(w, r)

require.Equal(t, 200, w.Code)
require.Contains(t, w.Body.String(), "OpenAPI specification")
require.Equal(t, "response", w.Header().Get("X-Test-Response"))
})
}
40 changes: 25 additions & 15 deletions options.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,19 @@ import (
)

type OpenAPIConfig struct {
DisableSwagger bool // If true, the server will not serve the swagger ui nor the openapi json spec
DisableLocalSave bool // If true, the server will not save the openapi json spec locally
SwaggerUrl string // URL to serve the swagger ui
JsonUrl string // URL to serve the openapi json spec
JsonFilePath string // Local path to save the openapi json spec
DisableSwagger bool // If true, the server will not serve the swagger ui nor the openapi json spec
DisableLocalSave bool // If true, the server will not save the openapi json spec locally
SwaggerUrl string // URL to serve the swagger ui
UIHandler func(specURL string) http.Handler // Handler to serve the openapi ui from spec url
JsonUrl string // URL to serve the openapi json spec
JsonFilePath string // Local path to save the openapi json spec
}

var defaultOpenAPIConfig = OpenAPIConfig{
SwaggerUrl: "/swagger",
JsonUrl: "/swagger/openapi.json",
JsonFilePath: "doc/openapi.json",
UIHandler: DefaultOpenAPIHandler,
}

type Server struct {
Expand All @@ -47,8 +49,7 @@ type Server struct {

basePath string

OpenApiSpec openapi3.T // OpenAPI spec generated by the server
UIHandler func(specURL string) http.Handler // Handler to serve the openapi ui from spec url
OpenApiSpec openapi3.T // OpenAPI spec generated by the server

Security Security

Expand Down Expand Up @@ -89,7 +90,6 @@ func NewServer(options ...func(*Server)) *Server {
OpenApiSpec: NewOpenApiSpec(),

OpenAPIConfig: defaultOpenAPIConfig,
UIHandler: defaultOpenAPIHandler,

Security: NewSecurity(),
}
Expand Down Expand Up @@ -267,18 +267,28 @@ func WithoutLogger() func(*Server) {

func WithOpenAPIConfig(openapiConfig OpenAPIConfig) func(*Server) {
return func(s *Server) {
s.OpenAPIConfig = openapiConfig
if openapiConfig.JsonUrl != "" {
s.OpenAPIConfig.JsonUrl = openapiConfig.JsonUrl
}

if openapiConfig.SwaggerUrl != "" {
s.OpenAPIConfig.SwaggerUrl = openapiConfig.SwaggerUrl
}

if openapiConfig.JsonFilePath != "" {
s.OpenAPIConfig.JsonFilePath = openapiConfig.JsonFilePath
}

if s.OpenAPIConfig.JsonUrl == "" {
s.OpenAPIConfig.JsonUrl = defaultOpenAPIConfig.JsonUrl
if openapiConfig.UIHandler != nil {
s.OpenAPIConfig.UIHandler = openapiConfig.UIHandler
}

if s.OpenAPIConfig.SwaggerUrl == "" {
s.OpenAPIConfig.SwaggerUrl = defaultOpenAPIConfig.SwaggerUrl
if openapiConfig.DisableSwagger {
s.OpenAPIConfig.DisableSwagger = true
}

if s.OpenAPIConfig.JsonFilePath == "" {
s.OpenAPIConfig.JsonFilePath = defaultOpenAPIConfig.JsonFilePath
if openapiConfig.DisableLocalSave {
s.OpenAPIConfig.DisableLocalSave = true
}

if !validateJsonSpecLocalPath(s.OpenAPIConfig.JsonFilePath) {
Expand Down
Loading