feat(api): expose transport config snapshot

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-04-02 06:38:05 +00:00
parent 3b75dc1701
commit 8a23545a67
3 changed files with 101 additions and 17 deletions

View file

@ -4,7 +4,6 @@ package api
import (
"slices"
"strings"
)
// OpenAPISpecBuilder returns a SpecBuilder populated from the engine's current
@ -18,6 +17,7 @@ func (e *Engine) OpenAPISpecBuilder() *SpecBuilder {
return &SpecBuilder{}
}
transport := e.TransportConfig()
builder := &SpecBuilder{
Title: e.swaggerTitle,
Description: e.swaggerDesc,
@ -33,22 +33,13 @@ func (e *Engine) OpenAPISpecBuilder() *SpecBuilder {
ExternalDocsURL: e.swaggerExternalDocsURL,
}
if e.swaggerEnabled || strings.TrimSpace(e.swaggerPath) != "" {
builder.SwaggerPath = resolveSwaggerPath(e.swaggerPath)
}
if e.graphql != nil {
builder.GraphQLPath = e.graphql.path
builder.GraphQLPlayground = e.graphql.playground
}
if e.wsHandler != nil || strings.TrimSpace(e.wsPath) != "" {
builder.WSPath = resolveWSPath(e.wsPath)
}
if e.sseBroker != nil || strings.TrimSpace(e.ssePath) != "" {
builder.SSEPath = resolveSSEPath(e.ssePath)
}
builder.PprofEnabled = e.pprofEnabled
builder.ExpvarEnabled = e.expvarEnabled
builder.SwaggerPath = transport.SwaggerPath
builder.GraphQLPath = transport.GraphQLPath
builder.GraphQLPlayground = transport.GraphQLPlayground
builder.WSPath = transport.WSPath
builder.SSEPath = transport.SSEPath
builder.PprofEnabled = transport.PprofEnabled
builder.ExpvarEnabled = transport.ExpvarEnabled
return builder
}

View file

@ -149,6 +149,49 @@ func TestEngine_Good_OpenAPISpecBuilderCarriesEngineMetadata(t *testing.T) {
}
}
func TestEngine_Good_TransportConfigCarriesEngineMetadata(t *testing.T) {
gin.SetMode(gin.TestMode)
broker := api.NewSSEBroker()
e, err := api.New(
api.WithSwagger("Engine API", "Engine metadata", "2.0.0"),
api.WithSwaggerPath("/docs"),
api.WithWSPath("/socket"),
api.WithWSHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})),
api.WithGraphQL(newTestSchema(), api.WithPlayground(), api.WithGraphQLPath("/gql")),
api.WithSSE(broker),
api.WithSSEPath("/events"),
api.WithPprof(),
api.WithExpvar(),
)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
cfg := e.TransportConfig()
if cfg.SwaggerPath != "/docs" {
t.Fatalf("expected swagger path /docs, got %q", cfg.SwaggerPath)
}
if cfg.GraphQLPath != "/gql" {
t.Fatalf("expected graphql path /gql, got %q", cfg.GraphQLPath)
}
if !cfg.GraphQLPlayground {
t.Fatal("expected GraphQL playground to be enabled")
}
if cfg.WSPath != "/socket" {
t.Fatalf("expected ws path /socket, got %q", cfg.WSPath)
}
if cfg.SSEPath != "/events" {
t.Fatalf("expected sse path /events, got %q", cfg.SSEPath)
}
if !cfg.PprofEnabled {
t.Fatal("expected pprof to be enabled")
}
if !cfg.ExpvarEnabled {
t.Fatal("expected expvar to be enabled")
}
}
func TestEngine_Good_OpenAPISpecBuilderExportsDefaultSwaggerPath(t *testing.T) {
gin.SetMode(gin.TestMode)

50
transport.go Normal file
View file

@ -0,0 +1,50 @@
// SPDX-License-Identifier: EUPL-1.2
package api
import "strings"
// TransportConfig captures the configured transport endpoints and flags for an Engine.
//
// It is intentionally small and serialisable so callers can inspect the active HTTP
// surface without rebuilding an OpenAPI document.
type TransportConfig struct {
SwaggerPath string
GraphQLPath string
GraphQLPlayground bool
WSPath string
SSEPath string
PprofEnabled bool
ExpvarEnabled bool
}
// TransportConfig returns the currently configured transport metadata for the engine.
//
// The result snapshots the Engine state at call time and normalises any configured
// URL paths using the same rules as the runtime handlers.
func (e *Engine) TransportConfig() TransportConfig {
if e == nil {
return TransportConfig{}
}
cfg := TransportConfig{
GraphQLPlayground: e.graphql != nil && e.graphql.playground,
PprofEnabled: e.pprofEnabled,
ExpvarEnabled: e.expvarEnabled,
}
if e.swaggerEnabled || strings.TrimSpace(e.swaggerPath) != "" {
cfg.SwaggerPath = resolveSwaggerPath(e.swaggerPath)
}
if e.graphql != nil {
cfg.GraphQLPath = e.graphql.path
}
if e.wsHandler != nil || strings.TrimSpace(e.wsPath) != "" {
cfg.WSPath = resolveWSPath(e.wsPath)
}
if e.sseBroker != nil || strings.TrimSpace(e.ssePath) != "" {
cfg.SSEPath = resolveSSEPath(e.ssePath)
}
return cfg
}