package main import ( "net/http" "tercul/internal/adapters/graphql" "tercul/internal/observability" "tercul/internal/platform/auth" "github.com/99designs/gqlgen/graphql/handler" "github.com/99designs/gqlgen/graphql/playground" "github.com/prometheus/client_golang/prometheus" ) // NewAPIServer creates a new http.ServeMux and configures it with all the API routes, // including the GraphQL endpoint, GraphQL Playground, and Prometheus metrics. func NewAPIServer( resolver *graphql.Resolver, jwtManager *auth.JWTManager, metrics *observability.Metrics, logger *observability.Logger, reg *prometheus.Registry, ) *http.ServeMux { // Configure the GraphQL server c := graphql.Config{Resolvers: resolver} c.Directives.Binding = graphql.Binding // Create the core GraphQL handler graphqlHandler := handler.NewDefaultServer(graphql.NewExecutableSchema(c)) graphqlHandler.SetErrorPresenter(graphql.NewErrorPresenter()) // Create the middleware chain for the GraphQL endpoint. // Middlewares are applied from bottom to top. var chain http.Handler chain = graphqlHandler chain = metrics.PrometheusMiddleware(chain) chain = observability.LoggingMiddleware(logger)(chain) // Must run after auth and tracing chain = auth.GraphQLAuthMiddleware(jwtManager)(chain) chain = observability.TracingMiddleware(chain) chain = observability.RequestIDMiddleware(chain) // Create a new ServeMux and register all handlers mux := http.NewServeMux() mux.Handle("/query", chain) mux.Handle("/playground", playground.Handler("GraphQL Playground", "/query")) mux.Handle("/metrics", observability.PrometheusHandler(reg)) return mux }