From 3c2f5512a80ec2093dead3f60a9c370a4919b7d9 Mon Sep 17 00:00:00 2001 From: Virgil Date: Thu, 2 Apr 2026 12:47:42 +0000 Subject: [PATCH] feat(api): add GraphQL config snapshot Co-Authored-By: Virgil --- graphql.go | 39 +++++++++++++++++++++++++++++++++++++++ graphql_config_test.go | 42 ++++++++++++++++++++++++++++++++++++++++++ transport.go | 19 ++++++++++--------- 3 files changed, 91 insertions(+), 9 deletions(-) create mode 100644 graphql_config_test.go diff --git a/graphql.go b/graphql.go index 1deff9d..4825b6a 100644 --- a/graphql.go +++ b/graphql.go @@ -22,6 +22,45 @@ type graphqlConfig struct { playground bool } +// GraphQLConfig captures the configured GraphQL endpoint settings for an Engine. +// +// It is intentionally small and serialisable so callers can inspect the active +// GraphQL surface without reaching into the internal handler configuration. +// +// Example: +// +// cfg := api.GraphQLConfig{Enabled: true, Path: "/graphql", Playground: true} +type GraphQLConfig struct { + Enabled bool + Path string + Playground bool +} + +// GraphQLConfig returns the currently configured GraphQL settings for the engine. +// +// The result snapshots the Engine state at call time and normalises any configured +// URL path using the same rules as the runtime handlers. +// +// Example: +// +// cfg := engine.GraphQLConfig() +func (e *Engine) GraphQLConfig() GraphQLConfig { + if e == nil { + return GraphQLConfig{} + } + + cfg := GraphQLConfig{ + Enabled: e.graphql != nil, + Playground: e.graphql != nil && e.graphql.playground, + } + + if e.graphql != nil { + cfg.Path = normaliseGraphQLPath(e.graphql.path) + } + + return cfg +} + // GraphQLOption configures a GraphQL endpoint. // // Example: diff --git a/graphql_config_test.go b/graphql_config_test.go new file mode 100644 index 0000000..4ef1617 --- /dev/null +++ b/graphql_config_test.go @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: EUPL-1.2 + +package api_test + +import ( + "testing" + + "github.com/gin-gonic/gin" + + api "dappco.re/go/core/api" +) + +func TestEngine_GraphQLConfig_Good_SnapshotsCurrentSettings(t *testing.T) { + gin.SetMode(gin.TestMode) + + e, err := api.New( + api.WithGraphQL(newTestSchema(), api.WithPlayground(), api.WithGraphQLPath(" /gql/ ")), + ) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + cfg := e.GraphQLConfig() + if !cfg.Enabled { + t.Fatal("expected GraphQL to be enabled") + } + if cfg.Path != "/gql" { + t.Fatalf("expected GraphQL path /gql, got %q", cfg.Path) + } + if !cfg.Playground { + t.Fatal("expected GraphQL playground to be enabled") + } +} + +func TestEngine_GraphQLConfig_Good_EmptyOnNilEngine(t *testing.T) { + var e *api.Engine + + cfg := e.GraphQLConfig() + if cfg.Enabled || cfg.Path != "" || cfg.Playground { + t.Fatalf("expected zero-value GraphQL config, got %+v", cfg) + } +} diff --git a/transport.go b/transport.go index 5a5de5c..59c7517 100644 --- a/transport.go +++ b/transport.go @@ -40,20 +40,21 @@ func (e *Engine) TransportConfig() TransportConfig { } cfg := TransportConfig{ - SwaggerEnabled: e.swaggerEnabled, - GraphQLEnabled: e.graphql != nil, - GraphQLPlayground: e.graphql != nil && e.graphql.playground, - WSEnabled: e.wsHandler != nil, - SSEEnabled: e.sseBroker != nil, - PprofEnabled: e.pprofEnabled, - ExpvarEnabled: e.expvarEnabled, + SwaggerEnabled: e.swaggerEnabled, + WSEnabled: e.wsHandler != nil, + SSEEnabled: e.sseBroker != nil, + PprofEnabled: e.pprofEnabled, + ExpvarEnabled: e.expvarEnabled, } + gql := e.GraphQLConfig() + cfg.GraphQLEnabled = gql.Enabled + cfg.GraphQLPlayground = gql.Playground if e.swaggerEnabled || strings.TrimSpace(e.swaggerPath) != "" { cfg.SwaggerPath = resolveSwaggerPath(e.swaggerPath) } - if e.graphql != nil { - cfg.GraphQLPath = normaliseGraphQLPath(e.graphql.path) + if gql.Path != "" { + cfg.GraphQLPath = gql.Path } if e.wsHandler != nil || strings.TrimSpace(e.wsPath) != "" { cfg.WSPath = resolveWSPath(e.wsPath)