feat(openapi): export runtime transport metadata

Expose GraphQL, WebSocket, SSE, and debug endpoint metadata alongside the existing Swagger UI path in generated OpenAPI documents.

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-04-02 06:08:44 +00:00
parent 29f4c23977
commit 9b24a46fd5
2 changed files with 34 additions and 0 deletions

View file

@ -89,6 +89,22 @@ func (sb *SpecBuilder) Build(groups []RouteGroup) ([]byte, error) {
if swaggerPath := strings.TrimSpace(sb.SwaggerPath); swaggerPath != "" {
spec["x-swagger-ui-path"] = normaliseSwaggerPath(swaggerPath)
}
if graphqlPath := sb.effectiveGraphQLPath(); graphqlPath != "" {
spec["x-graphql-path"] = normaliseOpenAPIPath(graphqlPath)
spec["x-graphql-playground"] = sb.GraphQLPlayground
}
if wsPath := strings.TrimSpace(sb.WSPath); wsPath != "" {
spec["x-ws-path"] = normaliseOpenAPIPath(wsPath)
}
if ssePath := strings.TrimSpace(sb.SSEPath); ssePath != "" {
spec["x-sse-path"] = normaliseOpenAPIPath(ssePath)
}
if sb.PprofEnabled {
spec["x-pprof-enabled"] = true
}
if sb.ExpvarEnabled {
spec["x-expvar-enabled"] = true
}
if sb.TermsOfService != "" {
spec["info"].(map[string]any)["termsOfService"] = sb.TermsOfService

View file

@ -64,6 +64,24 @@ func TestEngine_Good_OpenAPISpecBuilderCarriesEngineMetadata(t *testing.T) {
if got := spec["x-swagger-ui-path"]; got != "/docs" {
t.Fatalf("expected x-swagger-ui-path=/docs, got %v", got)
}
if got := spec["x-graphql-path"]; got != "/gql" {
t.Fatalf("expected x-graphql-path=/gql, got %v", got)
}
if got := spec["x-graphql-playground"]; got != true {
t.Fatalf("expected x-graphql-playground=true, got %v", got)
}
if got := spec["x-ws-path"]; got != "/socket" {
t.Fatalf("expected x-ws-path=/socket, got %v", got)
}
if got := spec["x-sse-path"]; got != "/events" {
t.Fatalf("expected x-sse-path=/events, got %v", got)
}
if got := spec["x-pprof-enabled"]; got != true {
t.Fatalf("expected x-pprof-enabled=true, got %v", got)
}
if got := spec["x-expvar-enabled"]; got != true {
t.Fatalf("expected x-expvar-enabled=true, got %v", got)
}
contact, ok := info["contact"].(map[string]any)
if !ok {