Giter VIP home page Giter VIP logo

wundergraph / cosmo Goto Github PK

View Code? Open in Web Editor NEW
529.0 529.0 48.0 22.88 MB

The open-source solution to building, maintaining, and collaborating on GraphQL Federation at Scale. An alternative to Apollo Studio and GraphOS.

Home Page: https://cosmo-docs.wundergraph.com/

License: Apache License 2.0

Makefile 0.09% TypeScript 52.50% JavaScript 0.22% Dockerfile 0.09% Shell 0.19% Smarty 0.22% FreeMarker 0.63% SCSS 0.06% Go 10.83% HTML 34.97% CSS 0.20%
apollo apollo-federation federation gateway graphql

cosmo's Introduction

wunderctl Star us on GitHub PRs welcome License Apache 2 Enterprise support

Quickstart   •   Website   •   Docs   •   Examples   •   Blog

Join our Discord Server Tweet at us on Twitter

Love WunderGraph? Give us a ⭐ on GitHub!

What is WunderGraph?

WunderGraph is a Backend for Frontend (BFF) Framework designed to optimize Developer Workflows through API Composition.

At its core, WunderGraph combines two patterns, API Gateway and BFF with the concept of a package manager, making API composition as simple as npm install. Our mantra is: Compose, don't integrate.

API Composition is a new pattern that allows you to interact with a heterogeneous set of APIs as if they were a single unified API. This not just eliminates a lot of glue code, but also allows you to reason about the API Dependencies of an application. Do you actually know what APIs and Services your application depends on? WunderGraph can easily answer this question for you, and even gives you analytics and observability into what APIs and Endpoints are used by your application and what the quality of service your API dependencies provide.

WunderGraph in a nutshell

Here's how WunderGraph works:

  1. Compose your APIs
// .wundergraph/wundergraph.config.ts

import { NextJsTemplate } from '@wundergraph/nextjs/dist/template';

// introspect a PostgreSQL database
const pg = introspect.postgresql({
  apiNamespace: 'pg',
  databaseURL: new EnvironmentVariable('PG_DATABASE_URL'),
});

// introspect the Stripe API using OpenAPI
const stripe = introspect.openApiV2({
  apiNamespace: 'stripe',
  source: {
    kind: 'file',
    filePath: './stripe.yaml',
  },
  headers: (builder) => builder.addClientRequestHeader('Authorization', `Bearer ${process.env.STRIPE_SECRET_KEY}`),
});

// introspect the Shopify Storefront API using GraphQL
const shopify = introspect.graphql({
  apiNamespace: 'shopify',
  url: 'https://my-shop.myshopify.com/api/2021-07/graphql.json',
  headers: (builder) =>
    builder.addStaticHeader('X-Shopify-Storefront-Access-Token', new EnvironmentVariable('SHOPIFY_STOREFRONT_TOKEN')),
});

configureWunderGraphApplication({
  // compose the APIs into a unified WunderGraph API
  apis: [pg, stripe, shopify],

  // generate type-safe clients for your Frontend
  codeGenerators: [
    {
      templates: [new NextJsTemplate()],
      path: '../web/components/generated',
    },
  ],
});

WunderGraph allows you to create a code pipeline to introspect and compose multiple APIs into a unified API. This makes it easy to update an API dependency without a single click.

  1. Define an Operation

By combining the introspected APIs, WunderGraph generates a unified GraphQL Schema across all APIs. All we have to do is define an Operation and call it from our Frontend. You can create a GraphQL operation or a TypeScript operation. Both are type-safe. TypeScript operations allows you to add custom logic e.g aggregating data from multiple APIs, defining custom input validation, etc.

GraphQL TypeScript
# .wundergraph/operations/users/ByID.graphql
query ($id: String!) {
  user: pg_findFirstUser(where: { id: { equals: $id } }) {
    id
    email
    name
    bio
  }
}
// .wundergraph/operations/users/CustomByID.ts
import { createOperation, z } from '../../generated/wundergraph.factory';

export default createOperation.query({
  // Input validation
  input: z.object({
    id: z.string(),
  }),
  handler: async ({ input }) => {
    // Call into your virtual graph, type-safe
    const { errors, data } = await operations.query({
      operationName: 'users/ByID',
      input: {
        id: input.id,
      },
    });

    return {
      ...data,
    };
  },
});
  1. Call the Operation from your Frontend

As you define Operations, WunderGraph automatically generates a type-safe client for your Frontend, supporting all major Frontend Frameworks like React, NextJS, Remix, Astro, Svelte, Expo, Vue, etc...

// web/pages/profile.ts

import { useQuery } from '../../components/generated/nextjs';

export default async function ProfilePage(props) {
  const { data } = await useQuery({
    operationName: 'users/CustomByID', // or 'users/ByID'
    input: {
      id: props.params.id,
    },
  });

  return (
    <div>
      <h1>{data.user.id}</h1>
      <p>{data.user.name}</p>
    </div>
  );
}

In the same vein, you could now add Authentication, Authorization, file uploads, etc...

Getting started

The easiest way to get started from scratch is to use the following command:

npx create-wundergraph-app my-project --example nextjs

If you already have an existing project, you can add WunderGraph to it by running:

npx create-wundergraph-app --init

Examples:

We've got a comprehensive list of examples to get you started. The best way to try them out is by cloning the mono-repo.

Advanced Examples:

The WunderGraph Stack

WunderGraph is made up of the three core components:

  • wunderctl: A command line tool to create, deploy and manage your WunderGraph application.
  • SDK: Create, configure & extend your WunderGraph Application with TypeScript.

Core features

  • APIs as Dependencies - Define which data sources your frontend depends on and WunderGraph handles the rest. Say goodbye to unmaintainable glue-code, focus on adding real business value.
  • Backend for Frontend Architecture - WunderGraph lives next to your frontend code, but can also be used stand alone as an API Gateway. Whatever you're building, you can always depend on the same great DX.
  • End-to-End-TypeSafety - Start new projects in minutes with powerful conventions and code generation. WunderGraph generates instant, typesafe API clients, including authentication and file uploads.
  • API Composition with Namespacing - WunderGraph is the only tool that allows you to compose multiple APIs into a single unified API without naming collisions or manual configuration thanks to API namespacing.

Architecture & Key Differentiators

You can learn more about the architecture of WunderGraph and why we’ve built it this way in the architecture section.

How does WunderGraph work

This section provides a high-level overview of how WunderGraph works and its most consumer centric components. For a more thorough introduction, visit the architecture documentation.

After initializing your WunderGraph application, you have a NPM package and a .wundergraph folder. This folder contains the following files:

  • wundergraph.config.ts - The primary config file for your WunderGraph application. Add data-sources and more.
  • wundergraph.operations.ts - Configure authentication, caching and more for a specific or all operations.
  • wundergraph.server.ts - The hooks server to hook into different lifecycle events of your gateway.

As a user of WunderGraph, you add your data-sources and authentication configuration to the wundergraph.config.ts file. You will then define your Operations by creating either a *.graphql or *.ts file in the .wundergraph/operations/ directory. Using GraphQL, you can directly interact with the GraphQL Schema of your data-sources. If you'd like to add more customization, you can also use TypeScript to define custom operations.

All Operations are then compiled into JSON-RPC and served by the WunderGraph Gateway. You can either use one of the generated type-safe clients, or try out the API using the Postman Collection or OpenAPI Specification which will be generated in the .wundergraph/generated directory.

Contributing

Read the CONTRIBUTING.md to learn how to contribute to WunderGraph.

Security

We are thankful for any and all security reports. Please read the SECURITY.md to learn how to report any security concerns to WunderGraph.

Community & Support

  • GitHub Issues. Best for: bugs and errors you encounter using WunderGraph.
  • Email Support. Best for: specific questions around WunderGraph as an early enterprise adopter.
  • Slack Support. Best for: problems with WunderGraph as an enterprise customer.
  • Discord. Best for: sharing your applications and hanging out with the community.
  • Feedback and Feature Requests. Best for: discussing and voting on feature requests and giving feedback to our developers.

Enterprise

We're a small but growing team of API Enthusiasts, thrilled to help you get the best Developer Experience of working with APIs. Our Support Plans are tailored to help your teams get the most out of WunderGraph. We love building close relationships with our customers, allowing us to continuously improve the product and iterate fast. Our sales team is available to talk with you about your project needs, pricing information, support plans, and custom-built features.

Use this Link to contact our sales team for a demo.

cosmo's People

Contributors

aenimus avatar alejandrobelleza avatar clayne11 avatar cs-clarence avatar devsergiy avatar fiam avatar github-actions[bot] avatar jensneuse avatar jivusayrus avatar matt-potter avatar pagebakers avatar paulpdaniels avatar rickpasetto avatar seendsouza avatar starptech avatar thisisnithin avatar vasily-polonsky avatar voslartomas avatar wunderhawk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

cosmo's Issues

Support linux/arm64/v8

Component(s)

router, controlplane, studio

Is your feature request related to a problem? Please describe.

Hi Team,

Could you add multi-arch (arm64) support to the Docker images soon? This will help Cosmo reaches more users on ARM64 systems. Thoughts?

Thanks,
Harry

Describe the solution you'd like

multi-arch support

Describe alternatives you've considered

No response

Additional context

No response

No Federated and Subgraphs after update

Component(s)

controlplane

Component version

latest

wgc version

latest

controlplane version

latest

router version

latest

What happened?

Description

After the update to the latest helm chart the Federated Graph and Subgraphs are not shown anymore in the detail views for the (sub)graph. In the Organization Dashboard we can still see the (sub)graphs but as soon as we want to get detailed information the page shows an error. The network tab in the developer tools shows that the /wg.cosmo.platform.v1.PlatformService/GetFederatedGraphs request returns a result but the /wg.cosmo.platform.v1.PlatformService/GetFederatedGraphByName request for this graph returns

{
    "response": {
        "code": "ERR_NOT_FOUND",
        "details": "Federated graph 'admin-app-graph' not found"
    },
    "subgraphs": [],
    "graphRequestToken": ""
}

Steps to Reproduce

Since there is no helm chart versioning its hard to tell which change caused this but I installed the helm chart last week on wednesday.

Expected Result

Migration should work

Actual Result

Environment information

Environment

OS: (e.g., "Ubuntu 20.04")
Package Manager: pnpm, npm, yarn, etc
Compiler(if manually compiled): (e.g., "go 14.2")

Router configuration

No response

Router execution config

No response

Log output

No response

Additional context

No response

Show subgraph name in trace

Component(s)

No response

Is your feature request related to a problem? Please describe.

At Uber, our routing uses the same URL for every service and our networking router looks at a specific header to determine which service to route a request to. Currently, the traces only show the URL (which is always the same), and I have to dig into the headers to see the service name.

It would be great to see the subgraph name instead of / as well as the URL:
Screenshot 2023-12-13 at 11 25 22

Describe the solution you'd like

Currently the title of the box says "Fetch from subgraph <#>". Replace this with "Fetch from subgraph < name > ".

Describe alternatives you've considered

No response

Additional context

No response

helm chart registry

Is your feature request related to a problem? Please describe.

Are the helm charts released to some kind of registry to use them?

Describe the solution you'd like

Push helm charts to registry

Describe alternatives you've considered

No response

Additional context

No response

Composition error with @override and @key directives

Component(s)

composition

What happened?

Description

Trying to compose multiple subgraphs having entity with @key directive in our monolith graph and trying to migrate to new service fails with an error.

Steps to Reproduce

monolith

type Opportunity @key(fields: "id") {
  id: ID!
  activeTaskCount: Int!
}

new service

type Opportunity @key(fields: "id") @shareable {
  id: ID!
  activeTaskCount: Int! @override(from: "monolith")
}

Expected Result

To be able to compose such subgraphs.

Actual Result

 bento1a                      │ The object "Opportunity" defines the same fields in multiple subgraphs without the "@shareable" directive:             │
│                              │  The field "activeTaskCount" is defined and declared "@shareable" in the following subgraph: "newservice-bento1a".          │
│                              │  However, it is not declared "@shareable" in the following subgraph: "monolith".     

Component version

0.15.0

Environment information

Environment

Router configuration

No response

Router execution config

No response

Log output

No response

Additional context

No response

[Feature Request] Cache introspection query

We have a large schema (~10MB, ~250.000 lines, ~10K types). The introspection query currently takes a couple seconds to responsd. It might be useful to cache the result of introspection (the router is aware when the schema changes so it's safe to do so).

Schema search not displaying queries/mutaions

Component(s)

studio

Component version

latest

wgc version

latest

controlplane version

latest

router version

latest

What happened?

We host a self-managed version of cosmo studio. The search in the schema view (/schema) does not return search results for queries or mutations. I think this is one of the important use cases to find a query/mutation and inspect inputs etc.

Environment information

Environment

OS: (e.g., "Ubuntu 20.04")
Package Manager: pnpm, npm, yarn, etc
Compiler(if manually compiled): (e.g., "go 14.2")

Router configuration

No response

Router execution config

No response

Log output

No response

Additional context

No response

/live and /ready endpoints requests are logged as info + included in tracing in studio

Component(s)

router

What happened?

Description

Logs are being polluted with /ready and /live request logs, it could be probably debug only? As if we change log level to error only we will lost information at the start of the pod.

And these requests show up inside tracing in studio.

Steps to Reproduce

Expected Result

Actual Result

Component version

0.54.2

Environment information

Environment

OS: (e.g., "Ubuntu 20.04")
Package Manager: pnpm, npm, yarn, etc
Compiler(if manually compiled): (e.g., "go 14.2")

Router configuration

No response

Router execution config

No response

Log output

No response

Additional context

No response

Router - Subgraph errors not logged

Component(s)

router

Is your feature request related to a problem? Please describe.

For an operation team view, subgraph errors not logged make the product complicated to manage as this is requiring the full cosmo stack or a tracing stack to know which request is in error or not. We are somehow blind.

Describe the solution you'd like

Log subgraph errors if any occured when a query is made

Describe alternatives you've considered

No response

Additional context

No response

PS: Thanks for your product !

[Bug] Federated query results in internal service error

Component(s)

router

What happened?

Description

Queries to individual services can be served but a federated query spanning two subgraphs results in an internal service error. The same query can be served by the original wundergraph and apollo router/gateway.

Steps to Reproduce

With this repo https://github.com/james-cooke-doxyme/graphql-poc make the query

query usersWithRooms {
  users {
    edges {
      node {
        id
        firstName
        lastName
        rooms {
          nodes {
            id
            name
          }
        }
      }
    }
  }
}

Which spans two services users and rooms.

Expected Result

{
  "data": {
    "users": {
      "edges": [
        {
          "node": {
            "id": "59a48dc5-cb64-4cd7-81fb-ba68d0d505d9",
            "firstName": "Rebekah",
            "lastName": "Windler",
            "rooms": {
              "nodes": []
            }
          }
        },
...
}

Actual Result

Error from the router

{"level":"info","time":1696580403776,"msg":"/graphql","hostname":"8ae332730bfd","pid":1,"component":"@wundergraph/router","status":400,"method":"POST","path":"/graphql","query":"","ip":"172.17.0.1:59122","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36","latency":0.05540525,"time":"2023-10-06T08:20:03Z","configVersion":"c11d110e-ee02-4fa8-9fc0-980ae295a7fe","requestID":"8ae332730bfd/DAMTTJbjaS-000019","federatedGraphName":"poc"}
{"level":"error","time":1696580460818,"msg":"internal error","hostname":"8ae332730bfd","pid":1,"component":"@wundergraph/router","reqId":"8ae332730bfd/DAMTTJbjaS-000020","error":"1 error occurred:\n\t* bad datasource configuration - could not plan the operation\n\n","stacktrace":"github.com/wundergraph/cosmo/router/core.logInternalErrors\n\tgithub.com/wundergraph/cosmo/router/core/graphql_handler.go:253\ngithub.com/wundergraph/cosmo/router/core.writeRequestErrorsFromReport\n\tgithub.com/wundergraph/cosmo/router/core/graphql_handler.go:262\ngithub.com/wundergraph/cosmo/router/core.(*GraphQLHandler).ServeHTTP\n\tgithub.com/wundergraph/cosmo/router/core/graphql_handler.go:126\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2122\ngithub.com/go-chi/chi.(*Mux).routeHTTP\n\tgithub.com/go-chi/[email protected]/mux.go:436\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2122\ngithub.com/wundergraph/cosmo/router/core.(*Router).newServer.func3.1.1\n\tgithub.com/wundergraph/cosmo/router/core/router.go:618\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2122\ngithub.com/wundergraph/cosmo/router/core.(*PreHandler).Handler.func1\n\tgithub.com/wundergraph/cosmo/router/core/graphql_prehandler.go:240\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2122\ngithub.com/wundergraph/cosmo/router/internal/trace.(*Middleware).Handler.func1\n\tgithub.com/wundergraph/cosmo/router/internal/trace/middleware.go:43\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2122\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.(*middleware).serveHTTP\n\tgo.opentelemetry.io/contrib/instrumentation/net/http/[email protected]/handler.go:217\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.NewMiddleware.func1.1\n\tgo.opentelemetry.io/contrib/instrumentation/net/http/[email protected]/handler.go:81\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2122\ngithub.com/go-chi/chi.(*Mux).ServeHTTP\n\tgithub.com/go-chi/[email protected]/mux.go:70\ngithub.com/go-chi/chi.(*Mux).Mount.func1\n\tgithub.com/go-chi/[email protected]/mux.go:311\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2122\ngithub.com/go-chi/chi.(*Mux).routeHTTP\n\tgithub.com/go-chi/[email protected]/mux.go:436\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2122\ngithub.com/wundergraph/cosmo/router/internal/handler/cors.(*cors).ServeHTTP\n\tgithub.com/wundergraph/cosmo/router/internal/handler/cors/config.go:74\ngithub.com/wundergraph/cosmo/router/internal/handler/requestlogger.(*handler).ServeHTTP\n\tgithub.com/wundergraph/cosmo/router/internal/handler/requestlogger/requestlogger.go:68\ngithub.com/go-chi/chi/middleware.RealIP.func1\n\tgithub.com/go-chi/[email protected]/middleware/realip.go:34\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2122\ngithub.com/go-chi/chi/middleware.RequestID.func1\n\tgithub.com/go-chi/[email protected]/middleware/request_id.go:76\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2122\ngithub.com/wundergraph/cosmo/router/internal/handler/recovery.(*handler).ServeHTTP\n\tgithub.com/wundergraph/cosmo/router/internal/handler/recovery/recovery.go:103\ngithub.com/go-chi/chi.(*Mux).ServeHTTP\n\tgithub.com/go-chi/[email protected]/mux.go:87\nnet/http.serverHandler.ServeHTTP\n\tnet/http/server.go:2936\nnet/http.(*conn).serve\n\tnet/http/server.go:1995"}

Component version

Router image b5dd9d175be2

Environment information

Environment

OS: (e.g., "Ubuntu 20.04")
Package Manager: pnpm, npm, yarn, etc
Compiler(if manually compiled): (e.g., "go 14.2")

Router configuration

version: "1"

# General router options
#graph:
#  name: "poc"

log_level: "info"
listen_addr: "0.0.0.0:4000"
controlplane_url: "https://cosmo-cp.wundergraph.com"
playground_enabled: true
introspection_enabled: true
json_log: true
shutdown_delay: 15s
grace_period: 20s
poll_interval: 10s
health_check_path: "/health"
readiness_check_path: "/health/ready"
liveness_check_path: "/health/live"

Router execution config

No response

Log output

No response

Additional context

No response

router doesn't work when the schema returned by the _service.sdl includes the _service or _entities fields

Component(s)

router

Component version

0.54.2

wgc version

0.35.0

controlplane version

not using controlplane

router version

0.54.2

Description

Router returns HTTP 500 error when the schema returned by the _service.sdl includes the _service or _entities fields.

I'm building a custom supgraph library and I included these things in the _service.sdl field, because I only need to work with Federation 2.0 and, as stated here (https://www.apollographql.com/docs/federation/subgraph-spec#required-resolvers-for-introspection), they should only be omitted when support for Federation 1.0 is needed.

This error is printed in the logs:

{"level":"error","time":1709041748292,"caller":"core/graphql_handler.go:357","msg":"internal error","hostname": (redacted),"pid":10948,"component":"@wundergraph/router","service_version":"0.69.0","reqId": (redacted),"error":"1 error occurred:\n\t* nodesResolvableVisitor: could not select the datasource to resolve Query.mediaplans_results on a path query.mediaplans_results\n\n","stacktrace":"github.com/wundergraph/cosmo/router/core.logInternalErrorsFromReport\n\tgithub.com/wundergraph/cosmo/router/core/graphql_handler.go:357\ngithub.com/wundergraph/cosmo/router/core.(*PreHandler).writeOperationError\n\tgithub.com/wundergraph/cosmo/router/core/graphql_prehandler.go:418\ngithub.com/wundergraph/cosmo/router/core.(*PreHandler).Handler-fm.(*PreHandler).Handler.func1\n\tgithub.com/wundergraph/cosmo/router/core/graphql_prehandler.go:293\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2166\ngithub.com/wundergraph/cosmo/router/core.(*WebsocketHandler).ServeHTTP\n\tgithub.com/wundergraph/cosmo/router/core/websocket.go:176\ngithub.com/go-chi/chi/v5.(*Mux).ServeHTTP\n\tgithub.com/go-chi/chi/[email protected]/mux.go:73\ngithub.com/go-chi/chi/v5.(*Mux).Mount.func1\n\tgithub.com/go-chi/chi/[email protected]/mux.go:315\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2166\ngithub.com/go-chi/chi/v5.(*Mux).routeHTTP\n\tgithub.com/go-chi/chi/[email protected]/mux.go:443\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2166\ngithub.com/wundergraph/cosmo/router/pkg/cors.(*cors).ServeHTTP\n\tgithub.com/wundergraph/cosmo/router/pkg/cors/config.go:66\ngithub.com/wundergraph/cosmo/router/internal/requestlogger.(*handler).ServeHTTP\n\tgithub.com/wundergraph/cosmo/router/internal/requestlogger/requestlogger.go:99\ngithub.com/wundergraph/cosmo/router/pkg/trace.(*Middleware).Handler.func1\n\tgithub.com/wundergraph/cosmo/router/pkg/trace/middleware.go:45\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2166\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.(*middleware).serveHTTP\n\tgo.opentelemetry.io/contrib/instrumentation/net/http/[email protected]/handler.go:229\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.NewMiddleware.func1.1\n\tgo.opentelemetry.io/contrib/instrumentation/net/http/[email protected]/handler.go:81\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2166\ngithub.com/go-chi/chi/v5/middleware.RealIP.func1\n\tgithub.com/go-chi/chi/[email protected]/middleware/realip.go:36\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2166\ngithub.com/go-chi/chi/v5/middleware.RequestID.func1\n\tgithub.com/go-chi/chi/[email protected]/middleware/request_id.go:76\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2166\ngithub.com/wundergraph/cosmo/router/internal/recoveryhandler.(*handler).ServeHTTP\n\tgithub.com/wundergraph/cosmo/router/internal/recoveryhandler/recovery.go:103\ngithub.com/wundergraph/cosmo/router/core.(*Router).newServer.func2.1\n\tgithub.com/wundergraph/cosmo/router/core/router.go:836\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2166\ngithub.com/go-chi/chi/v5.(*Mux).ServeHTTP\n\tgithub.com/go-chi/chi/[email protected]/mux.go:90\nnet/http.serverHandler.ServeHTTP\n\tnet/http/server.go:3137\nnet/http.(*conn).serve\n\tnet/http/server.go:2039"}

Steps to Reproduce

Have the Query._service.sdl field's return value include this in at least one subgraph:


extend type Query {
  _service: _Service!
}

extend type Query {
  _entities(representations: [_Any!]!): [_Entity!]!
}

Expected Result

Router should handle request correctly

Actual Result

HTTP 500: internal server error

{"errors":[{"message":"internal server error"}],"data":null}

Persisted operations from apollo client returns 500

Component(s)

Controlplane

What happened?

Description

We are trying to move from Apollo router to Cosmo router and the thing is we are using APQ (Automated Persisted Queries) in apollo client, which expects first send hashed operation and if it does not exist on the server it will send another request with query content so router can cache it. But cosmo router sends 500 response and is not able even trigger second request from client. Is this something known as you don't support apollo's APQ for instance? Or is this a bug?

Steps to Reproduce

Expected Result

Actual Result

Component version

v0.47.2 (controlplane)

Environment information

Environment

OS: (e.g., "Ubuntu 20.04")
Package Manager: pnpm, npm, yarn, etc
Compiler(if manually compiled): (e.g., "go 14.2")

Router configuration

No response

Router execution config

No response

Log output

No response

Additional context

No response

[Feature Request] Cache results of parsing and validation

To speed up responses of repeated queries it'd be great to cache results of request parsing and validation as it adds some overhead and it's not necessary to run every time (parse cache can be indefinite, validation cache should be flushed when loading a new schema).

The router already caches the execution plan for queries. Btw, is there a particular reason to cache it for only 1 hour?

// cache the prepared plan for 1 hour
h.planCache.SetWithTTL(operationContext.hash, prepared, 1, time.Hour)

Playground could take schema from registry not from introspection

Component(s)

studio

Is your feature request related to a problem? Please describe.

Due to security reasons we don't want to expose introspection in our production clusters, but that is a problem with Cosmo's playground as it relies on introspection, without that we are not able to use it.

Describe the solution you'd like

It could automatically take latests compose schema from registry instead.

Describe alternatives you've considered

No response

Additional context

No response

[Feature Request] Add support for response compression

We're working with large schema and responses (up to 10s of MB). Cosmo router currently doesn't support compression of response compression between client and router and between the router and subgraphs to cosmo router which makes it very slow for larger responses.

cosmo.wundergraph.com keeps refreshing - no interactions possible

Component(s)

studio

Component version

cloud

wgc version

0.43.2

controlplane version

cloud

router version

What happened?

If possible, please create a PR with a failing test to illustrate the issue clearly.

Otherwise, please attach a minimum reproduction through a GitHub repository that includes

essential information such as the relevant subgraph SDLs.

Please also make sure that the instructions for the reproduction are clear, tested, and fully accurate.

Description

Steps to Reproduce

  1. Login to cosmo.wundergraph.com
  2. Try navigate or do anything

Expected Result

UI should be consistent

Actual Result

UI keeps refreshing, which prevents me from doing anything at all

Environment information

Tried on multiple devices and browsers:

  • Google Pixel with Firefox Mobile
  • MacOS Ventura 13.6.1 with Firefox 123.0b3
  • MacOS Ventura 13.6.1 with Chrome 121.0.6167.139
  • MacOS Ventura 13.6.1 with Chrome 121.0.6167.139 (incognito, no plugins)
    Bildschirmfoto 2024-02-23 um 19 46 22
Bildschirmaufnahme.2024-02-23.um.22.11.20.mov

Router configuration

No response

Router execution config

No response

Log output

No response

Additional context

No response

Latest wgc fails on every command

Component(s)

cli

Component version

latest

wgc version

latest

controlplane version

latest

router version

latest

What happened?

If possible, please create a PR with a failing test to illustrate the issue clearly.

Otherwise, please attach a minimum reproduction through a GitHub repository that includes

essential information such as the relevant subgraph SDLs.

Please also make sure that the instructions for the reproduction are clear, tested, and fully accurate.

Description

Error: Failed to check for updates. You can disable update check by setting env DISABLE_UPDATE_CHECK=true. fetch is not defined

And it seems it is failing to install some packages as it needs node version 18?

+ npm install -g wgc@latest
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: '[email protected]',
npm WARN EBADENGINE   required: { node: '>=18' },
npm WARN EBADENGINE   current: { node: 'v16.20.2', npm: '8.10.0' }
npm WARN EBADENGINE }

This used to work few days ago.

Steps to Reproduce

Expected Result

Actual Result

Environment information

Environment

OS: (e.g., "Ubuntu 20.04")
Package Manager: pnpm, npm, yarn, etc
Compiler(if manually compiled): (e.g., "go 14.2")

Router configuration

No response

Router execution config

No response

Log output

No response

Additional context

No response

test

Component(s)

studio

What happened?

Description

Steps to Reproduce

Expected Result

Actual Result

Component version

3232

Environment information

Environment

OS: (e.g., "Ubuntu 20.04")
Package Manager: pnpm, npm, yarn, etc
Compiler(if manually compiled): (e.g., "go 14.2")

Router configuration

No response

Router execution config

No response

Log output

No response

Additional context

No response

Proxy headers from Subgraphs to client

Component(s)

No response

Is your feature request related to a problem? Please describe.

I want to pass headers from subgraph back to client, but only found a way to pass from router to subgraph. Would be cool to have this in proxy settings as well. Found a way to create a custom module to modify headers using custom modules. Would be nice to have this feature as it is much easier, you don't have to build a router and you need only configure yaml file.

Describe the solution you'd like

headers:
  all: (subgraphs)
    response:

Describe alternatives you've considered

No response

Additional context

No response

Self hosted cosmo needs billing plan

Component(s)

controlplane, studio

What happened?

Description

I used the helm chart to run cosmo in our Kubernetes cluster since we decided to self-host. The problem is that it seems there is a billing plan required for different actions e.g. creating a new organization. Is this intentional?

Steps to Reproduce

Install cosmo in k8s cluster with helm chart and try to create a new organization.

Expected Result

Organization is created with given name

Actual Result

An error is shown

image

Component version

0.0.1

Environment information

Environment

OS: (e.g., "Ubuntu 20.04")
Package Manager: pnpm, npm, yarn, etc
Compiler(if manually compiled): (e.g., "go 14.2")

Router configuration

No response

Router execution config

No response

Log output

No response

Additional context

No response

headers propagation

For some reason, I can't propagate headers to my subgraph. I specifically want to propagate the Authorization header to the subgraph

headers:
  all:
    request:
      - op: "propagate"
        named: Authorization
      - op: "propagate"
        matching:  .*

From the documentation, the above code should work.

My router is currently deployed using a Dockerfile:

FROM ghcr.io/wundergraph/cosmo/router:latest

WORKDIR /

COPY config.yaml ./

EXPOSE 3002

DB::Exception: Database cosmo does not exist. (UNKNOWN_DATABASE) (version 23.8.3.48 (official build))

Component(s)

controlplane

Component version

latest (from git)

wgc version

NA

controlplane version

ghcr.io/wundergraph/cosmo/controlplane@sha256:b226292a8fddcd4cb51c6be03ccefb62d111c7b01a78922cc7054531ba1a0f0e

router version

NA

What happened?

If possible, please create a PR with a failing test to illustrate the issue clearly.

Otherwise, please attach a minimum reproduction through a GitHub repository that includes

essential information such as the relevant subgraph SDLs.

Please also make sure that the instructions for the reproduction are clear, tested, and fully accurate.

Description

I have installed cosmo with helm using values.full.yaml and after logged in I'm getting 500 responses for https://controlplane.k-dev.khealth.xyz/wg.cosmo.platform.v1.PlatformService/GetFederatedGraphs.

In the cluster I observe these logs for controlplane:

{"level":"error","time":"2024-02-22T13:41:50.521Z","pid":1,"hostname":"cosmo-controlplane-b58dbd478-rfd8v","msg":"Code: 81. DB::Exception: Database
cosmo does not exist. (UNKNOWN_DATABASE) (version 23.8.3.48 (official build))\n"}
{"level":"error","time":"2024-02-22T13:41:52.242Z","pid":1,"hostname":"cosmo-controlplane-b58dbd478-rfd8v","msg":"Code: 81. DB::Exception: Database
cosmo does not exist. (UNKNOWN_DATABASE) (version 23.8.3.48 (official build))\n"}
{"level":"error","time":"2024-02-22T13:41:54.762Z","pid":1,"hostname":"cosmo-controlplane-b58dbd478-rfd8v","msg":"Code: 81. DB::Exception: Database
cosmo does not exist. (UNKNOWN_DATABASE) (version 23.8.3.48 (official build))\n"}

at the same time in clickhouse:

2024.02.22 13:41:54.760463 [ 330 ] {} <Error> DynamicQueryHandler: Code: 81. DB::Exception: Database cosmo does not exist. (UNKNOWN_DATABASE), Stack

0. DB::Exception::Exception(DB::Exception::MessageMasked&&, int, bool) @ 0x000000000c630397 in /opt/bitnami/clickhouse/bin/clickhouse
1. DB::Exception::Exception<String>(int, FormatStringHelperImpl<std::type_identity<String>::type>, String&&) @ 0x00000000071404cd in /opt/bitnami/cl
2. DB::DatabaseCatalog::assertDatabaseExists(String const&) const @ 0x00000000116ee96f in /opt/bitnami/clickhouse/bin/clickhouse
3. DB::Context::setCurrentDatabase(String const&) @ 0x000000001163df42 in /opt/bitnami/clickhouse/bin/clickhouse
4. DB::HTTPHandler::processQuery(DB::HTTPServerRequest&, DB::HTMLForm&, DB::HTTPServerResponse&, DB::HTTPHandler::Output&, std::optional<DB::Current
5. DB::HTTPHandler::handleRequest(DB::HTTPServerRequest&, DB::HTTPServerResponse&) @ 0x00000000130e23c9 in /opt/bitnami/clickhouse/bin/clickhouse
6. DB::HTTPServerConnection::run() @ 0x0000000013153072 in /opt/bitnami/clickhouse/bin/clickhouse
7. Poco::Net::TCPServerConnection::start() @ 0x0000000015b3b9d4 in /opt/bitnami/clickhouse/bin/clickhouse
8. Poco::Net::TCPServerDispatcher::run() @ 0x0000000015b3cbd1 in /opt/bitnami/clickhouse/bin/clickhouse
9. Poco::PooledThread::run() @ 0x0000000015c73407 in /opt/bitnami/clickhouse/bin/clickhouse
10. Poco::ThreadImpl::runnableEntry(void*) @ 0x0000000015c716dc in /opt/bitnami/clickhouse/bin/clickhouse
11. start_thread @ 0x0000000000007ea7 in /lib/x86_64-linux-gnu/libpthread-2.31.so
12. ? @ 0x00000000000fba2f in /lib/x86_64-linux-gnu/libc-2.31.so
 (version 23.8.3.48 (official build))

Steps to Reproduce

deploy values.full.yaml as instructed in helm/cosmo/README.md

Expected Result

no errors

Actual Result

  1. can't fetch graph
  2. errors in clickhouse

Environment information

Environment

OS: (e.g., "Ubuntu 20.04")
Package Manager: pnpm, npm, yarn, etc
Compiler(if manually compiled): (e.g., "go 14.2")

Router configuration

No response

Router execution config

No response

Log output

No response

Additional context

No response

Clarification needed on subgraph naming and labeling for different environments

Hi,
I am currently playing with the federated graph system and trying to understand how to organize multiple projects and environments.

From the documentation, I understand you can have multiple subgraphs with different environments (dev or prod), but it is not working as I expected.

Scenario:
I have a Federated Graph called Animal with two subgraphs (Cat and Dog). Both of these subgraphs are labeled env=development and I want to promote these in a production environment.

Issue:
I attempted to create a new Federated Graph named Animal-Prod labeled env=production. However, I encountered an issue where I couldn't create subgraphs under Animal-Prod with the same names (Cat and Dog) but with the label env=production.

Questions:

  1. Is it a system constraint that prevents creating subgraphs with the same name across different federated graphs, even if they have distinct labels? is the intention to have Cat-dev and Cat-prod
  2. What is the recommended approach for promoting subgraphs from a development environment to production, ensuring that both versions coexist?

Any guidance or clarification on this would be greatly appreciated.

Rewrite header names on propagate to subgraphs

Component(s)

router

Is your feature request related to a problem? Please describe.

The migration from apollo to wundergraph requires changes to the applications. I think its better to provide similar configuration possibilities as the apollo router/gateway

Describe the solution you'd like

Extend the header configuration to be able to rename a header when propagating it to subgraphs.

Describe alternatives you've considered

No response

Additional context

No response

bug: Custom scalars always interpreted as string [confirmed]

Hi,
Currently it seems like the cosmo router does not handle custom scalars properly.
As an example, our subcharts have a custom scalar type LONG. When router receives a response from subchart including a long typed field, the router fails with following error:
"error":"invalid value type 'number' for path /data/_modelMetadata/modelHcn, expecting string, got: 5160. You can fix this by configuring this field as Int/Float/JSON Scalar" .
In ideal scenario, the router should just passthrough the value without applying any validation.
Apollo gateway handles this without issues.

Related issue: wundergraph/graphql-go-tools#530

Enable helm chart to use existing secrets

Component(s)

helm

Is your feature request related to a problem? Please describe.

The problem with the current helm chart is that you need to provide secret values in plain text in the values.yaml. For users who follow a gitops workflow, this is not the ideal solution because the secrets need to be pushed into a repo.

Describe the solution you'd like

Normally helm chart provide a possibility to define an existing secret name for the chart. In case this value is provided the helm chart does not create its secret resource.

Describe alternatives you've considered

No response

Additional context

No response

`concurrent map writes` in the module example

Component(s)

router

What happened?

Description

When using the module from the example, sometimes the error fatal error: concurrent map writes occurs

This happens if you set a debug breakpoint on ctx.ResponseWriter().Header().Set("myHeader", ctx.GetString("myValue")), restart the router and send a request

Steps to Reproduce

Run router with module use 0.54.0 tag

Expected Result

No error

Actual Result

ctx.ResponseWriter().Header().Set("myHeader", ctx.GetString("myValue")) -> fatal error: concurrent map writes

Component version

135a54f

Environment information

Environment

OS: macOS 14.2.1 (23C71) M1
Package Manager: wgc downloaded from npm
Compiler(if manually compiled): go1.21.4

Router configuration

version: "1"

# General router options
graph:
  name: "production"
  token: ""

log_level: "info"
listen_addr: "localhost:3002"
playground_enabled: true
introspection_enabled: true
json_log: true
shutdown_delay: 15s
grace_period: 20s
poll_interval: 10s
health_check_path: "/health"
readiness_check_path: "/health/ready"
liveness_check_path: "/health/live"
router_config_path: "config.json"

cors:
  allow_origins: ["*"]
  allow_methods:
    - HEAD
    - GET
    - POST
  allow_headers:
    - Origin
    - Content-Length
    - Content-Type
  allow_credentials: true
  max_age_minutes: 5m

# Config for custom modules   
# See "https://cosmo-docs.wundergraph.com/router/custom-modules" for more information   
modules:
  myModule:
    # Arbitrary values, unmarshalled by the module
    value: 1

Router execution config

No response

Log output

fatal error: concurrent map writes

goroutine 254 [running]:
net/textproto.MIMEHeader.Set(0x14001a40150, {0x101cea3a9, 0x8}, {0x101ce8ce8, 0x7})
        /opt/homebrew/opt/go/libexec/src/net/textproto/header.go:22 +0xbc
net/http.Header.Set(0x14001a40150, {0x101cea3a9, 0x8}, {0x101ce8ce8, 0x7})
        /opt/homebrew/opt/go/libexec/src/net/http/header.go:40 +0x34
github.com/wundergraph/cosmo/router/cmd/custom/module.(*MyModule).OnOriginResponse(0x14000420a60, 0x14002e1a360, {0x102362a90, 0x140009de900})
        /Users/dgridnev/projects/cosmo/router/cmd/custom/module/module.go:57 +0xa8
github.com/wundergraph/cosmo/router/core.(*CustomTransport).RoundTrip(0x1400027c960, 0x1400023cb00)
        /Users/dgridnev/projects/cosmo/router/core/transport.go:130 +0x318
net/http.send(0x1400023c800, {0x10234bbc0, 0x1400027c960}, {0xc16503202768d630, 0x73df475442, 0x102d3a380})
        /opt/homebrew/opt/go/libexec/src/net/http/client.go:260 +0x3a0
net/http.(*Client).send(0x140001a2f00, 0x1400023c800, {0xc16503202768d630, 0x73df475442, 0x102d3a380})
        /opt/homebrew/opt/go/libexec/src/net/http/client.go:181 +0xe0
net/http.(*Client).do(0x140001a2f00, 0x1400023c800)
        /opt/homebrew/opt/go/libexec/src/net/http/client.go:724 +0xdd0
net/http.(*Client).Do(0x140001a2f00, 0x1400023c800)
        /opt/homebrew/opt/go/libexec/src/net/http/client.go:590 +0x3c
github.com/wundergraph/graphql-go-tools/v2/pkg/engine/datasource/httpclient.Do(0x140001a2f00, {0x102359940, 0x14001065800}, {0x14001778d80, 0x169, 0x169}, {0x10234bc00, 0x14001064c90})
        /Users/dgridnev/go/pkg/mod/github.com/wundergraph/graphql-go-tools/[email protected]/pkg/engine/datasource/httpclient/nethttpclient.go:127 +0x518
github.com/wundergraph/graphql-go-tools/v2/pkg/engine/datasource/graphql_datasource.(*Source).Load(0x1400011a2f8, {0x102359940, 0x14001065800}, {0x14001778d80, 0x169, 0x169}, {0x10234bc00, 0x14001064c90})
        /Users/dgridnev/go/pkg/mod/github.com/wundergraph/graphql-go-tools/[email protected]/pkg/engine/datasource/graphql_datasource/graphql_datasource.go:1767 +0x8c
github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve.(*Loader).executeSourceLoad(0x1400357fb80, {0x102359978, 0x14003ff44b0}, {0x10234ea00, 0x1400011a2f8}, {0x140033f8000, 0x169, 0x280}, 0x14001064c90, 0x14000482580)
        /Users/dgridnev/go/pkg/mod/github.com/wundergraph/graphql-go-tools/[email protected]/pkg/engine/resolve/loader.go:898 +0x138c
github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve.(*Loader).loadEntityFetch(0x1400357fb80, {0x102359978, 0x14003ff44b0}, 0x14000219a40, {0x140014505c0, 0x1, 0x1}, 0x14002e92160)
        /Users/dgridnev/go/pkg/mod/github.com/wundergraph/graphql-go-tools/[email protected]/pkg/engine/resolve/loader.go:605 +0x878
github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve.(*Loader).loadFetch(0x1400357fb80, {0x102359978, 0x14003ff44b0}, {0x10234e320, 0x14000219a40}, {0x140014505c0, 0x1, 0x1}, 0x14002e92160)
        /Users/dgridnev/go/pkg/mod/github.com/wundergraph/graphql-go-tools/[email protected]/pkg/engine/resolve/loader.go:325 +0x4d8
github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve.(*Loader).resolveAndMergeFetch.func1()
        /Users/dgridnev/go/pkg/mod/github.com/wundergraph/graphql-go-tools/[email protected]/pkg/engine/resolve/loader.go:214 +0xf4
golang.org/x/sync/errgroup.(*Group).Go.func1()
        /Users/dgridnev/go/pkg/mod/golang.org/x/[email protected]/errgroup/errgroup.go:75 +0x80
created by golang.org/x/sync/errgroup.(*Group).Go in goroutine 124
        /Users/dgridnev/go/pkg/mod/golang.org/x/[email protected]/errgroup/errgroup.go:72 +0xfc

Additional context

Screenshot 2024-01-26 at 14 28 21

test

Component(s)

router

What happened?

Description

Steps to Reproduce

Expected Result

Actual Result

Component version

test

Environment information

Environment

OS: (e.g., "Ubuntu 20.04")
Package Manager: pnpm, npm, yarn, etc
Compiler(if manually compiled): (e.g., "go 14.2")

Router configuration

No response

Router execution config

No response

Log output

No response

Additional context

No response

bug: Alias for __typename fails [confirmed]

Hello, when using the cosmo router aliases lead to "unable to resolve" error.

This query works

query MyQuery {
  __typename
}

This one doesn't

query MyQuery {
  alias: __typename
}
{
  "errors": [
    {
      "message": "could not resolve response"
    }
  ]
}

This is the error from logs:

{"level":"error","time":1695131151680,"caller":"core/graphql_handler.go:160","msg":"unable to resolve GraphQL response","hostname":"<<HOSTNAME>>","pid":1,"component":"@wundergraph/router","reqId":"<<HOSTNAME>>/FXBPUpQ8mo-000058","error":"Key path not found","errorVerbose":"Key path not found\ngithub.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve.(*Loader).loadAndPostProcess\n\tgithub.com/wundergraph/graphql-go-tools/[email protected]/pkg/engine/resolve/load.go:731\ngithub.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve.(*Loader).resolveSingleFetch\n\tgithub.com/wundergraph/graphql-go-tools/[email protected]/pkg/engine/resolve/load.go:676\ngithub.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve.(*Loader).resolveFetch\n\tgithub.com/wundergraph/graphql-go-tools/[email protected]/pkg/engine/resolve/load.go:431\ngithub.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve.(*Loader).resolveObject\n\tgithub.com/wundergraph/graphql-go-tools/[email protected]/pkg/engine/resolve/load.go:274\ngithub.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve.(*Loader).resolveNode\n\tgithub.com/wundergraph/graphql-go-tools/[email protected]/pkg/engine/resolve/load.go:140\ngithub.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve.(*Loader).LoadGraphQLResponseData\n\tgithub.com/wundergraph/graphql-go-tools/[email protected]/pkg/engine/resolve/load.go:123\ngithub.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve.(*Resolver).ResolveGraphQLResponse\n\tgithub.com/wundergraph/graphql-go-tools/[email protected]/pkg/engine/resolve/resolve.go:132\ngithub.com/wundergraph/cosmo/router/core.(*GraphQLHandler).ServeHTTP\n\tgithub.com/wundergraph/cosmo/[email protected]/core/graphql_handler.go:152\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/go-chi/chi.(*Mux).routeHTTP\n\tgithub.com/go-chi/[email protected]/mux.go:436\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\nataccama.com/cosmo-router/src/module.MyModule.Middleware\n\tataccama.com/cosmo-router/src/module/module.go:91\ngithub.com/wundergraph/cosmo/router/core.(*Router).initModules.func1.1\n\tgithub.com/wundergraph/cosmo/[email protected]/core/router.go:291\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/wundergraph/cosmo/router/core.(*Router).newServer.func3.1.1\n\tgithub.com/wundergraph/cosmo/[email protected]/core/router.go:570\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/wundergraph/cosmo/router/internal/metric.(*Handler).Handler-fm.(*Handler).Handler.func1\n\tgithub.com/wundergraph/cosmo/[email protected]/internal/metric/handler.go:117\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/wundergraph/cosmo/router/core.(*PreHandler).Handler-fm.(*PreHandler).Handler.func1\n\tgithub.com/wundergraph/cosmo/[email protected]/core/graphql_prehandler.go:184\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/wundergraph/cosmo/router/internal/trace.(*Middleware).Handler.func1\n\tgithub.com/wundergraph/cosmo/[email protected]/internal/trace/middleware.go:43\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.(*middleware).serveHTTP\n\tgo.opentelemetry.io/contrib/instrumentation/net/http/[email protected]/handler.go:217\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.NewMiddleware.func1.1\n\tgo.opentelemetry.io/contrib/instrumentation/net/http/[email protected]/handler.go:81\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/go-chi/chi.(*Mux).ServeHTTP\n\tgithub.com/go-chi/[email protected]/mux.go:70\ngithub.com/go-chi/chi.(*Mux).Mount.func1\n\tgithub.com/go-chi/[email protected]/mux.go:311\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/go-chi/chi.(*Mux).routeHTTP\n\tgithub.com/go-chi/[email protected]/mux.go:436\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/wundergraph/cosmo/router/internal/handler/cors.(*cors).ServeHTTP\n\tgithub.com/wundergraph/cosmo/[email protected]/internal/handler/cors/config.go:74\ngithub.com/wundergraph/cosmo/router/internal/handler/requestlogger.(*handler).ServeHTTP\n\tgithub.com/wundergraph/cosmo/[email protected]/internal/handler/requestlogger/requestlogger.go:68\ngithub.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve.(*Loader).resolveSingleFetch\n\tgithub.com/wundergraph/graphql-go-tools/[email protected]/pkg/engine/resolve/load.go:678\ngithub.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve.(*Loader).resolveFetch\n\tgithub.com/wundergraph/graphql-go-tools/[email protected]/pkg/engine/resolve/load.go:431\ngithub.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve.(*Loader).resolveObject\n\tgithub.com/wundergraph/graphql-go-tools/[email protected]/pkg/engine/resolve/load.go:274\ngithub.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve.(*Loader).resolveNode\n\tgithub.com/wundergraph/graphql-go-tools/[email protected]/pkg/engine/resolve/load.go:140\ngithub.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve.(*Loader).LoadGraphQLResponseData\n\tgithub.com/wundergraph/graphql-go-tools/[email protected]/pkg/engine/resolve/load.go:123\ngithub.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve.(*Resolver).ResolveGraphQLResponse\n\tgithub.com/wundergraph/graphql-go-tools/[email protected]/pkg/engine/resolve/resolve.go:132\ngithub.com/wundergraph/cosmo/router/core.(*GraphQLHandler).ServeHTTP\n\tgithub.com/wundergraph/cosmo/[email protected]/core/graphql_handler.go:152\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/go-chi/chi.(*Mux).routeHTTP\n\tgithub.com/go-chi/[email protected]/mux.go:436\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\nataccama.com/cosmo-router/src/module.MyModule.Middleware\n\tataccama.com/cosmo-router/src/module/module.go:91\ngithub.com/wundergraph/cosmo/router/core.(*Router).initModules.func1.1\n\tgithub.com/wundergraph/cosmo/[email protected]/core/router.go:291\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/wundergraph/cosmo/router/core.(*Router).newServer.func3.1.1\n\tgithub.com/wundergraph/cosmo/[email protected]/core/router.go:570\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/wundergraph/cosmo/router/internal/metric.(*Handler).Handler-fm.(*Handler).Handler.func1\n\tgithub.com/wundergraph/cosmo/[email protected]/internal/metric/handler.go:117\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/wundergraph/cosmo/router/core.(*PreHandler).Handler-fm.(*PreHandler).Handler.func1\n\tgithub.com/wundergraph/cosmo/[email protected]/core/graphql_prehandler.go:184\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/wundergraph/cosmo/router/internal/trace.(*Middleware).Handler.func1\n\tgithub.com/wundergraph/cosmo/[email protected]/internal/trace/middleware.go:43\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.(*middleware).serveHTTP\n\tgo.opentelemetry.io/contrib/instrumentation/net/http/[email protected]/handler.go:217\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.NewMiddleware.func1.1\n\tgo.opentelemetry.io/contrib/instrumentation/net/http/[email protected]/handler.go:81\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/go-chi/chi.(*Mux).ServeHTTP\n\tgithub.com/go-chi/[email protected]/mux.go:70\ngithub.com/go-chi/chi.(*Mux).Mount.func1\n\tgithub.com/go-chi/[email protected]/mux.go:311\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/go-chi/chi.(*Mux).routeHTTP\n\tgithub.com/go-chi/[email protected]/mux.go:436\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/wundergraph/cosmo/router/internal/handler/cors.(*cors).ServeHTTP\n\tgithub.com/wundergraph/cosmo/[email protected]/internal/handler/cors/config.go:74\ngithub.com/wundergraph/cosmo/router/internal/handler/requestlogger.(*handler).ServeHTTP\n\tgithub.com/wundergraph/cosmo/[email protected]/internal/handler/requestlogger/requestlogger.go:68\ngithub.com/go-chi/chi/middleware.RealIP.func1\n\tgithub.com/go-chi/[email protected]/middleware/realip.go:34\ngithub.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve.(*Loader).resolveObject\n\tgithub.com/wundergraph/graphql-go-tools/[email protected]/pkg/engine/resolve/load.go:276\ngithub.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve.(*Loader).resolveNode\n\tgithub.com/wundergraph/graphql-go-tools/[email protected]/pkg/engine/resolve/load.go:140\ngithub.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve.(*Loader).LoadGraphQLResponseData\n\tgithub.com/wundergraph/graphql-go-tools/[email protected]/pkg/engine/resolve/load.go:123\ngithub.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve.(*Resolver).ResolveGraphQLResponse\n\tgithub.com/wundergraph/graphql-go-tools/[email protected]/pkg/engine/resolve/resolve.go:132\ngithub.com/wundergraph/cosmo/router/core.(*GraphQLHandler).ServeHTTP\n\tgithub.com/wundergraph/cosmo/[email protected]/core/graphql_handler.go:152\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/go-chi/chi.(*Mux).routeHTTP\n\tgithub.com/go-chi/[email protected]/mux.go:436\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\nataccama.com/cosmo-router/src/module.MyModule.Middleware\n\tataccama.com/cosmo-router/src/module/module.go:91\ngithub.com/wundergraph/cosmo/router/core.(*Router).initModules.func1.1\n\tgithub.com/wundergraph/cosmo/[email protected]/core/router.go:291\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/wundergraph/cosmo/router/core.(*Router).newServer.func3.1.1\n\tgithub.com/wundergraph/cosmo/[email protected]/core/router.go:570\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/wundergraph/cosmo/router/internal/metric.(*Handler).Handler-fm.(*Handler).Handler.func1\n\tgithub.com/wundergraph/cosmo/[email protected]/internal/metric/handler.go:117\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/wundergraph/cosmo/router/core.(*PreHandler).Handler-fm.(*PreHandler).Handler.func1\n\tgithub.com/wundergraph/cosmo/[email protected]/core/graphql_prehandler.go:184\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/wundergraph/cosmo/router/internal/trace.(*Middleware).Handler.func1\n\tgithub.com/wundergraph/cosmo/[email protected]/internal/trace/middleware.go:43\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.(*middleware).serveHTTP\n\tgo.opentelemetry.io/contrib/instrumentation/net/http/[email protected]/handler.go:217\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.NewMiddleware.func1.1\n\tgo.opentelemetry.io/contrib/instrumentation/net/http/[email protected]/handler.go:81\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/go-chi/chi.(*Mux).ServeHTTP\n\tgithub.com/go-chi/[email protected]/mux.go:70\ngithub.com/go-chi/chi.(*Mux).Mount.func1\n\tgithub.com/go-chi/[email protected]/mux.go:311\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/go-chi/chi.(*Mux).routeHTTP\n\tgithub.com/go-chi/[email protected]/mux.go:436\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/wundergraph/cosmo/router/internal/handler/cors.(*cors).ServeHTTP\n\tgithub.com/wundergraph/cosmo/[email protected]/internal/handler/cors/config.go:74\ngithub.com/wundergraph/cosmo/router/internal/handler/requestlogger.(*handler).ServeHTTP\n\tgithub.com/wundergraph/cosmo/[email protected]/internal/handler/requestlogger/requestlogger.go:68\ngithub.com/go-chi/chi/middleware.RealIP.func1\n\tgithub.com/go-chi/[email protected]/middleware/realip.go:34\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/go-chi/chi/middleware.RequestID.func1\n\tgithub.com/go-chi/[email protected]/middleware/request_id.go:76","stacktrace":"github.com/wundergraph/cosmo/router/core.(*GraphQLHandler).ServeHTTP\n\tgithub.com/wundergraph/cosmo/[email protected]/core/graphql_handler.go:160\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/go-chi/chi.(*Mux).routeHTTP\n\tgithub.com/go-chi/[email protected]/mux.go:436\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\nataccama.com/cosmo-router/src/module.MyModule.Middleware\n\tataccama.com/cosmo-router/src/module/module.go:91\ngithub.com/wundergraph/cosmo/router/core.(*Router).initModules.func1.1\n\tgithub.com/wundergraph/cosmo/[email protected]/core/router.go:291\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/wundergraph/cosmo/router/core.(*Router).newServer.func3.1.1\n\tgithub.com/wundergraph/cosmo/[email protected]/core/router.go:570\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/wundergraph/cosmo/router/internal/metric.(*Handler).Handler-fm.(*Handler).Handler.func1\n\tgithub.com/wundergraph/cosmo/[email protected]/internal/metric/handler.go:117\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/wundergraph/cosmo/router/core.(*PreHandler).Handler-fm.(*PreHandler).Handler.func1\n\tgithub.com/wundergraph/cosmo/[email protected]/core/graphql_prehandler.go:184\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/wundergraph/cosmo/router/internal/trace.(*Middleware).Handler.func1\n\tgithub.com/wundergraph/cosmo/[email protected]/internal/trace/middleware.go:43\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.(*middleware).serveHTTP\n\tgo.opentelemetry.io/contrib/instrumentation/net/http/[email protected]/handler.go:217\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.NewMiddleware.func1.1\n\tgo.opentelemetry.io/contrib/instrumentation/net/http/[email protected]/handler.go:81\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/go-chi/chi.(*Mux).ServeHTTP\n\tgithub.com/go-chi/[email protected]/mux.go:70\ngithub.com/go-chi/chi.(*Mux).Mount.func1\n\tgithub.com/go-chi/[email protected]/mux.go:311\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/go-chi/chi.(*Mux).routeHTTP\n\tgithub.com/go-chi/[email protected]/mux.go:436\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/wundergraph/cosmo/router/internal/handler/cors.(*cors).ServeHTTP\n\tgithub.com/wundergraph/cosmo/[email protected]/internal/handler/cors/config.go:74\ngithub.com/wundergraph/cosmo/router/internal/handler/requestlogger.(*handler).ServeHTTP\n\tgithub.com/wundergraph/cosmo/[email protected]/internal/handler/requestlogger/requestlogger.go:68\ngithub.com/go-chi/chi/middleware.RealIP.func1\n\tgithub.com/go-chi/[email protected]/middleware/realip.go:34\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/go-chi/chi/middleware.RequestID.func1\n\tgithub.com/go-chi/[email protected]/middleware/request_id.go:76\nnet/http.HandlerFunc.ServeHTTP\n\tnet/http/server.go:2136\ngithub.com/wundergraph/cosmo/router/internal/handler/recovery.(*handler).ServeHTTP\n\tgithub.com/wundergraph/cosmo/[email protected]/internal/handler/recovery/recovery.go:103\ngithub.com/go-chi/chi.(*Mux).ServeHTTP\n\tgithub.com/go-chi/[email protected]/mux.go:87\nnet/http.serverHandler.ServeHTTP\n\tnet/http/server.go:2938\nnet/http.(*conn).serve\n\tnet/http/server.go:2009"}

abstractlogger & byte-template have no license, and this poisons the project from a legal standpoint

One of our engineering team just asked us if they can bring in the Cosmo package. We ran a scan using FOSSA (our security and license tool) and it flagged the AbstractLogger project (direct dependency), and the byte-template project (direct dependency). Those projects don't have a license attached to them.

This may sound trivial, but the laws in the United States are clear. Any code which doesn't have a license is "all rights reserved". GitHub says this explicitly in the license documentation:

However, without a license, the default copyright laws apply, meaning that you retain all rights to your source code and no one may reproduce, distribute, or create derivative works from your work.

Can someone just attach the same Apache 2.0 license to these projects, to let us move forward?

Running the Router without any other components

Component(s)

router

Is your feature request related to a problem? Please describe.

I'm currently building up an entirely serverless GraphQL stack, and am looking for a Federation-compatible router that I fits with this infrastructure.

I'd love to give Cosmo Router a try, but it seems to be inextricably coupled with the other Cosmo components, making it impossible to run as a standalone thing (I might be wrong here). E.g. it needs to have a Control Plane to function, which would require both more services running (Control Plane doesn't seem like a thing you'd want to run in Lambda) and also means there is more stuff happening on the Router startup (registering to the Control Plane etc I guess).

I've done some examples here of various other Routers in AWS Lambda (Apollo Router needed some wrangling), and the story is generally not great when it comes to Cold Starts (1-1.5 seconds in general).

Describe the solution you'd like

I would love to be able to use the Cosmo Router completely on its own. I can already create the composed Supergraph Schema and provide that statically to the Router, but it still requires other services and e.g. a GRAPH_API_TOKEN.

Since it's a binary built with Go it would fit great in a serverless environment, with fast startup times and good performance.

Ideally, it would also expose a Lambda handler, but I don't mind getting creative and either taking a similar approach is with the Apollo Router in Lambda PoC or something else.

Describe alternatives you've considered

Alternative would be to not run it in a serverless environment, but that's a key part of the goal so not really an alternative 🤔

Additional context

N/A

List of one element in variables

Component(s)

router

What happened?

Description

I have arguments that are an array, when passing only one element not wrapped in square brackets I get the error Cannot return null for non-nullable field ..., without using a router the same query works fine. The problem occurs only with variables, with inline variables everything is fine.

Steps to Reproduce

Query:

query ContentPackMany($pagination: PageArguments!, $filtering: ContentPackFilter) {
  contentPackMany(pagination: $pagination, filtering: $filtering) {
    edges {
      node {
        id
      }
    }
  }
}

Variables:

{
  "pagination": {
    "first": 10
  },
  "filtering": {
    "locationIDManyVS": "01HF6W8TW637RBETVCD9KGRR08"
  }
}

Filter input:

input ContentPackFilter {
  ...
  locationIDManyVS: [ID]
  ...
}

Expected Result

The router must accept one element from the list, not wrapped in square brackets, and pass the request to the service.

Actual Result

The router gives an error. The request does not reach the service

{
  "errors": [
    {
      "message": "Cannot return null for non-nullable field Query.contentPackMany.contentPackMany.",
      "path": [
        "contentPackMany",
        "contentPackMany"
      ]
    }
  ],
  "data": null
}

Component version

v0.33.1

Environment information

No response

Router configuration

No response

Router execution config

No response

Log output

No response

Additional context

No response

Subscription routing does not seem to work

Component(s)

router

What happened?

Description

When I configure router with two subgraphs, one of which has a subscription, and try to subscribe, subscription seems to be alive, but messages are not coming in. No errors are visible on router logs.

I've tried to subscribe directly on the subgraph - subscription works.

federated config.json seems to contain correct data:

...
"subscription": {
  "enabled": true,
  "url": {
    "staticVariableContent": "ws://localhost:8080/subscriptions"
  },
  "protocol": "GRAPHQL_SUBSCRIPTION_PROTOCOL_WS"
},
...

Tested both websockets with wscat, only the subgraph one returns new messages:

➜  wscat -c ws://localhost:8080/subscriptions --subprotocol graphql-transport-ws
Connected (press CTRL+C to quit)
> {"type":"connection_init","payload":{}}
< {"type":"connection_ack"}
> {"id":"52a8498d-2e6f-47f4-8358-23009642e1bd","type":"subscribe","payload":{"query":"subscription {...}"}}
< {"id":"52a8498d-2e6f-47f4-8358-23009642e1bd","payload":{"data":{...}},"type":"next"}
wscat -c ws://localhost:3002/graphql --subprotocol graphql-transport-ws
Connected (press CTRL+C to quit)
> {"type":"connection_init","payload":{}}
< {"type":"connection_ack"}
> {"id":"52a8498d-2e6f-47f4-8358-23009642e1bd","type":"subscribe","payload":{"query":"subscription {...}"}}

Steps to Reproduce

Federate a sub-graph with subscription & try to subscribe

Expected Result

Messages are coming in

Actual Result

No messages from are coming in

Component version

0.54.2-darwin-amd64

Environment information

Environment

OS: macOs 14.2.1
Package Manager: -
Compiler(if manually compiled): -

Router configuration

headers:
  all:
    request:
      - op: "propagate"
        matching: .*
cors:
  allow_origins: ["*"]
  allow_methods: ["*"]
  allow_headers: ["*"]

router_config_path: config.json
json_log: false
dev_mode: true
log_level: debug
listen_addr: "0.0.0.0:3002"
graph:
  name: "local"
  token: ""

Router execution config

version: 1

subgraphs:
  - name: local-app
    routing_url: http://localhost:8080/graphql
    subscription:
      url: ws://localhost:8080/subscriptions
      protocol: ws
    introspection:
      url: http://localhost:8080/graphql
  - name: app
    routing_url: https://remote-app.net/graphql
    introspection:
      url: https://remote-app.net/graphql

Log output

11:34:56 AM DEBUG maxprocs/maxprocs.go:47 maxprocs: Leaving GOMAXPROCS=10: CPU quota undefined {"component": "@wundergraph/router", "service_version": "0.54.2"}
11:34:56 AM WARN core/router.go:303 No graph token provided. The following features are disabled. Not recommended for Production. {"component": "@wundergraph/router", "service_version": "0.54.2", "features": ["Schema Usage Tracking", "Persistent operations"]}
11:34:56 AM WARN core/router.go:318 Development mode enabled. This should only be used for testing purposes {"component": "@wundergraph/router", "service_version": "0.54.2"}
11:34:56 AM INFO metric/prometheus.go:43 Prometheus metrics enabled {"component": "@wundergraph/router", "service_version": "0.54.2", "listen_addr": "127.0.0.1:8088", "endpoint": "/metrics"}
11:34:56 AM INFO core/router.go:608 Static router config provided. Polling is disabled. Updating router config is only possible by providing a config. {"component": "@wundergraph/router", "service_version": "0.54.2"}
11:34:56 AM WARN core/router.go:800 Advanced Request Tracing (ART) is enabled in development mode but requires a graph token to work in production. For more information see https://cosmo-docs.wundergraph.com/router/advanced-request-tracing-art {"component": "@wundergraph/router", "service_version": "0.54.2"}
11:34:56 AM INFO core/router.go:830 Serving GraphQL playground {"component": "@wundergraph/router", "service_version": "0.54.2", "url": "http://0.0.0.0:3002"}
11:34:56 AM INFO core/router.go:901 GraphQL endpoint {"component": "@wundergraph/router", "service_version": "0.54.2", "method": "POST", "url": "http://0.0.0.0:3002/graphql"}
11:34:56 AM INFO core/router.go:400 Server listening {"component": "@wundergraph/router", "service_version": "0.54.2", "listen_addr": "0.0.0.0:3002", "playground": true, "introspection": true, "config_version": ""}
11:35:01 AM INFO core/websocket_stats.go:99 WebSocket Stats {"component": "@wundergraph/router", "service_version": "0.54.2", "open_connections": 0, "active_subscriptions": 0}
11:35:06 AM INFO core/websocket_stats.go:99 WebSocket Stats {"component": "@wundergraph/router", "service_version": "0.54.2", "open_connections": 0, "active_subscriptions": 0}
11:35:11 AM INFO core/websocket_stats.go:99 WebSocket Stats {"component": "@wundergraph/router", "service_version": "0.54.2", "open_connections": 0, "active_subscriptions": 0}
11:35:13 AM DEBUG core/websocket.go:690 Websocket connection {"component": "@wundergraph/router", "service_version": "0.54.2", "protocol": "graphql-transport-ws"}
11:35:13 AM INFO requestlogger/requestlogger.go:102 /graphql {"component": "@wundergraph/router", "service_version": "0.54.2", "status": 0, "method": "GET", "path": "/graphql", "query": "", "ip": "[::1]:58778", "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", "latency": 0.007909708, "time": "2024-01-18T09:35:13Z", "config_version": "", "request_id": "Pauliuss-MacBook-Pro.local/RM1ryUrbd7-000001", "federated_graph_name": "local"}
11:35:16 AM INFO core/websocket_stats.go:99 WebSocket Stats {"component": "@wundergraph/router", "service_version": "0.54.2", "open_connections": 1, "active_subscriptions": 1}
11:35:21 AM INFO core/websocket_stats.go:99 WebSocket Stats {"component": "@wundergraph/router", "service_version": "0.54.2", "open_connections": 1, "active_subscriptions": 1}
11:35:26 AM INFO core/websocket_stats.go:99 WebSocket Stats {"component": "@wundergraph/router", "service_version": "0.54.2", "open_connections": 1, "active_subscriptions": 1}

Additional context

No response

Router - Forward generated Request-Id to subgraph

Component(s)

router

Is your feature request related to a problem? Please describe.

As an operation team member, I would like to forward the generated request-id (generated by chi middleware if request doesn't have it) to subgraph.

Describe the solution you'd like

In configuration and using the "Header manipulation" feature, I would like to be able to forward X-Request-Id (even if it is generated by router backend) to subgraph backends.

Something like this:

headers:
  all: # Header rules for all origin requests.
    request:
      - op: "propagate"
        named: X-Request-Id

Describe alternatives you've considered

No response

Additional context

No response

Is it possible to access composed super graph schema inside module?

Component(s)

router

Is your feature request related to a problem? Please describe.

We need to have access to composed supergraph, to be able to find out some information about directives, queries etc.

Describe the solution you'd like

If we can have access either to already parsed or just string/file supergraph it would be great.

Describe alternatives you've considered

No response

Additional context

No response

Is that possible to contribute a piece of content to your engineering blog?

Component(s)

router

Is your feature request related to a problem? Please describe.

I want to contribute to WunderGraph engineering blog and not sure how I can do that.

Describe the solution you'd like

It would be awesome to contact someone responsible for the engineering blog of Wundergraph so that person would tell me what are conditions to accept a contribution.

Describe alternatives you've considered

I am considering to write to other GraphQL engineering blogs.

Additional context

I work at the Zalando GraphQL platform, organize Berlin GraphQL, interested in the Open Federation project, and write primarily in Rust and TypeScript.

Demo fails to start up ("Not authenticated")

Component(s)

No response

What happened?

👋 hi!

I'm trying to start up the make create-cli-demo and hitting the following:

...
Failed to create federated graph production.
Not authenticated
Failed to create subgraph 'employees'.
Not authenticated
Failed to create subgraph 'family'.
Not authenticated
Failed to create subgraph 'hobbies'.
Not authenticated
Failed to create subgraph 'products'.
Not authenticated
Failed to update subgraph employees.
Not authenticated
Failed to update subgraph family.
Not authenticated
Failed to update subgraph hobbies.
Not authenticated
Failed to update subgraph products.
Not authenticated
Could not create token for federated graph
Not authenticated
make: *** [create-cli-demo] Error 1

(This is from a freshly cloned copy of master:)

$ git rev-parse HEAD
cc4ed0e26ca1e4f58011c3a6c2c887d70a53a021

Full inputs/outputs of everything I ran+output from a freshly cloned copy of this repo:

$ make full-demo-up

docker compose -f docker-compose.full.yml --profile default up --build --remove-orphans --detach
WARN[0000] The "OTEL_AUTH_TOKEN" variable is not set. Defaulting to a blank string. 
WARN[0000] The "ROUTER_TOKEN" variable is not set. Defaulting to a blank string. 
WARN[0000] The "OTEL_AUTH_TOKEN" variable is not set. Defaulting to a blank string. 
WARN[0000] The "OTEL_AUTH_TOKEN" variable is not set. Defaulting to a blank string. 
WARN[0000] The "OTEL_AUTH_TOKEN" variable is not set. Defaulting to a blank string. 
[+] Running 89/23
 ✔ minio 8 layers [⣿⣿⣿⣿⣿⣿⣿⣿]      0B/0B      Pulled                                                                                                                                                          74.0s 
 ✔ studio 8 layers [⣿⣿⣿⣿⣿⣿⣿⣿]      0B/0B      Pulled                                                                                                                                                        109.6s 
 ✔ otelcollector 9 layers [⣿⣿⣿⣿⣿⣿⣿⣿⣿]      0B/0B      Pulled                                                                                                                                                135.1s 
 ✔ graphqlmetrics 14 layers [⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿]      0B/0B      Pulled                                                                                                                                          59.8s 
 ✔ clickhouse 10 layers [⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿]      0B/0B      Pulled                                                                                                                                                  84.4s 
 ✔ nats 3 layers [⣿⣿⣿]      0B/0B      Pulled                                                                                                                                                                11.0s 
 ✔ clickhouse-migration Pulled                                                                                                                                                                              120.5s 
 ✔ postgres 14 layers [⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿]      0B/0B      Pulled                                                                                                                                                43.6s 
 ✔ controlplane 3 layers [⣿⣿⣿]      0B/0B      Pulled                                                                                                                                                       109.6s 
 ✔ keycloak 3 layers [⣿⣿⣿]      0B/0B      Pulled                                                                                                                                                           176.7s 
 ✔ database-migration Pulled                                                                                                                                                                                110.7s 
 ✔ seed 5 layers [⣿⣿⣿⣿⣿]      0B/0B      Pulled                                                                                                                                                             116.1s 
                                                                                                                                                                                                                   
                                                                                                                                                                                                                   
                                                                                                                                                                                                                   
                                                                                                                                                                                                                   
                                                                                                                                                                                                                   
                                                                                                                                                                                                                   
                                                                                                                                                                                                                   
                                                                                                                                                                                                                   
                                                                                                                                                                                                                   
                                                                                                                                                                                                                   
                                                                                                                                                                                                                   
[+] Building 92.2s (21/21) FINISHED                                                                                                                                                       docker-container:default
 => [cdn internal] booting buildkit                                                                                                                                                                          10.5s
 => => pulling image moby/buildkit:buildx-stable-1                                                                                                                                                           10.0s
 => => creating container buildx_buildkit_default                                                                                                                                                             0.6s
 => [cdn internal] load build definition from Dockerfile                                                                                                                                                      0.0s
 => => transferring dockerfile: 845B                                                                                                                                                                          0.0s
 => [cdn internal] load metadata for docker.io/library/node:18-slim                                                                                                                                           1.0s
 => [cdn internal] load metadata for docker.io/library/node:18                                                                                                                                                1.0s
 => [cdn internal] load .dockerignore                                                                                                                                                                         0.0s
 => => transferring context: 235B                                                                                                                                                                             0.0s
 => [cdn builder  1/10] FROM docker.io/library/node:18@sha256:f152130c9bb77afd49873a26fcfb6da7971b451ae6db51901fb7e028ccc0ca75                                                                               49.0s
 => => resolve docker.io/library/node:18@sha256:f152130c9bb77afd49873a26fcfb6da7971b451ae6db51901fb7e028ccc0ca75                                                                                              0.0s
 => => sha256:14a483b4019c57e5d20b84f0dead37e7d18a923d0d6b93733ba764987811fb08 451B / 451B                                                                                                                    0.8s
 => => sha256:4d6fd19bb3529015bbf2f446047a2100bb99740a2592206ff01c71d99c650b3a 2.21MB / 2.21MB                                                                                                                0.7s
 => => sha256:9e989a3d4c61e0386963e4b08d2209b0ebc726545ffb86ae575cf05341dfd018 46.12MB / 46.12MB                                                                                                             21.5s
 => => sha256:5d0523b85d8eee65320a3c384cf038e35604aa467ca92c83270c201e574acd78 3.37kB / 3.37kB                                                                                                                0.6s
 => => sha256:ae58c7c06d64a1a86430205c774637c7615d1365a575b256801bb23390ad5260 202.48MB / 202.48MB                                                                                                           40.4s
 => => sha256:ddd8544b6e15c7a4096b1f48a67fb5bed2efba509fca597f1c164b582ab01c02 63.99MB / 63.99MB                                                                                                             16.3s
 => => sha256:6c641d36985b2db859fc64c43a6dbf7c25cdf73e5d16d107fab1d95a840bb4e1 23.58MB / 23.58MB                                                                                                             11.4s
 => => sha256:b66b4ecd3ecfb67b3b7a2a44b0199cbdfc94965c8bd3fefab75cd2e612799740 49.59MB / 49.59MB                                                                                                             13.6s
 => => extracting sha256:b66b4ecd3ecfb67b3b7a2a44b0199cbdfc94965c8bd3fefab75cd2e612799740                                                                                                                     1.2s
 => => extracting sha256:6c641d36985b2db859fc64c43a6dbf7c25cdf73e5d16d107fab1d95a840bb4e1                                                                                                                     0.4s
 => => extracting sha256:ddd8544b6e15c7a4096b1f48a67fb5bed2efba509fca597f1c164b582ab01c02                                                                                                                     1.3s
 => => extracting sha256:ae58c7c06d64a1a86430205c774637c7615d1365a575b256801bb23390ad5260                                                                                                                     5.0s
 => => extracting sha256:5d0523b85d8eee65320a3c384cf038e35604aa467ca92c83270c201e574acd78                                                                                                                     0.0s
 => => extracting sha256:9e989a3d4c61e0386963e4b08d2209b0ebc726545ffb86ae575cf05341dfd018                                                                                                                     1.6s
 => => extracting sha256:4d6fd19bb3529015bbf2f446047a2100bb99740a2592206ff01c71d99c650b3a                                                                                                                     0.0s
 => => extracting sha256:14a483b4019c57e5d20b84f0dead37e7d18a923d0d6b93733ba764987811fb08                                                                                                                     0.0s
 => [cdn stage-1 1/3] FROM docker.io/library/node:18-slim@sha256:fe687021c06383a2bc5eafa6db29b627ed28a55f6bdfbcea108f0c624b783c37                                                                            17.2s
 => => resolve docker.io/library/node:18-slim@sha256:fe687021c06383a2bc5eafa6db29b627ed28a55f6bdfbcea108f0c624b783c37                                                                                         0.0s
 => => sha256:392ddf2ad5566e652984d8e5de3952dcc8de5cab733680434b4a44549539dee6 2.67MB / 2.67MB                                                                                                                0.4s
 => => sha256:cb3d1a19897b82614ae137f8109dac0c53ae1ad903a58ec20732726e546b9661 451B / 451B                                                                                                                    0.1s
 => => sha256:b665ed4ee4f76abc12f31a233517ffd5ad39c72fa40ff7a06a9f93479da37f63 38.65MB / 38.65MB                                                                                                             16.2s
 => => sha256:dbc596c5cca5d4e99972bcb24d34d3c696b5b89b6b1777b2fca8eef3d1b8b5df 3.36kB / 3.36kB                                                                                                                0.3s
 => => sha256:24e221e92a36ab5b0075dd156b4f2ff095532a9b0927946cf6070bb1bea208b8 29.16MB / 29.16MB                                                                                                              8.3s
 => => extracting sha256:24e221e92a36ab5b0075dd156b4f2ff095532a9b0927946cf6070bb1bea208b8                                                                                                                     0.8s
 => => extracting sha256:dbc596c5cca5d4e99972bcb24d34d3c696b5b89b6b1777b2fca8eef3d1b8b5df                                                                                                                     0.0s
 => => extracting sha256:b665ed4ee4f76abc12f31a233517ffd5ad39c72fa40ff7a06a9f93479da37f63                                                                                                                     0.8s
 => => extracting sha256:392ddf2ad5566e652984d8e5de3952dcc8de5cab733680434b4a44549539dee6                                                                                                                     0.1s
 => => extracting sha256:cb3d1a19897b82614ae137f8109dac0c53ae1ad903a58ec20732726e546b9661                                                                                                                     0.0s
 => [cdn internal] load build context                                                                                                                                                                         0.8s
 => => transferring context: 27.93MB                                                                                                                                                                          0.8s
 => [cdn stage-1 2/3] WORKDIR /app                                                                                                                                                                            0.2s
 => [cdn builder  2/10] WORKDIR /app                                                                                                                                                                          0.1s
 => [cdn builder  3/10] RUN npm install --global pnpm@8                                                                                                                                                       1.4s
 => [cdn builder  4/10] COPY .npmrc package.json pnpm-lock.yaml pnpm-workspace.yaml ./                                                                                                                        0.0s
 => [cdn builder  5/10] COPY cdn-server/package.json cdn-server/                                                                                                                                              0.0s
 => [cdn builder  6/10] COPY cdn-server/cdn/package.json cdn-server/cdn/                                                                                                                                      0.0s
 => [cdn builder  7/10] RUN pnpm install --filter=./cdn-server/cdn --filter=./cdn-server --frozen-lockfile                                                                                                   14.9s
 => [cdn builder  8/10] COPY . /app/                                                                                                                                                                          0.5s
 => [cdn builder  9/10] RUN pnpm run --filter=./cdn-server/cdn --filter=./cdn-server build                                                                                                                    3.2s
 => [cdn builder 10/10] RUN pnpm --filter=./cdn-server --prod deploy pruned                                                                                                                                   3.9s
 => [cdn stage-1 3/3] COPY --from=builder /app/pruned .                                                                                                                                                       0.4s
 => [cdn] exporting to docker image format                                                                                                                                                                    5.9s
 => => exporting layers                                                                                                                                                                                       1.2s
 => => exporting manifest sha256:b50a7671a57c0626dc3f33540e864cbe6f0fba0a890480c833f119b4f8fd3b28                                                                                                             0.0s
 => => exporting config sha256:463765e5624fdf48636eb37d80c3e7bd165d64c384a65ed02cb6417bc5d46a6f                                                                                                               0.0s
 => => sending tarball                                                                                                                                                                                        4.7s
 => [cdn] importing to docker                                                                                                                                                                                 0.0s
[+] Running 18/18
 ✔ Network primary                              Created                                                                                                                                                       0.0s 
 ✔ Network full-cosmo_default                   Created                                                                                                                                                       0.0s 
 ✔ Volume "full-cosmo_clickhouse"               Created                                                                                                                                                       0.0s 
 ✔ Volume "full-cosmo_postgres"                 Created                                                                                                                                                       0.0s 
 ✔ Volume "full-cosmo_minio"                    Created                                                                                                                                                       0.0s 
 ✔ Container full-cosmo-clickhouse-1            Started                                                                                                                                                       0.1s 
 ✔ Container full-cosmo-studio-1                Started                                                                                                                                                       0.1s 
 ✔ Container full-cosmo-minio-1                 Started                                                                                                                                                       0.1s 
 ✔ Container full-cosmo-postgres-1              Started                                                                                                                                                       0.1s 
 ✔ Container full-cosmo-nats-1                  Started                                                                                                                                                       0.1s 
 ✔ Container full-cosmo-cdn-1                   Started                                                                                                                                                       0.1s 
 ✔ Container full-cosmo-otelcollector-1         Started                                                                                                                                                       0.0s 
 ✔ Container full-cosmo-clickhouse-migration-1  Started                                                                                                                                                       0.1s 
 ✔ Container full-cosmo-graphqlmetrics-1        Started                                                                                                                                                       0.0s 
 ✔ Container full-cosmo-keycloak-1              Started                                                                                                                                                       0.1s 
 ✔ Container full-cosmo-database-migration-1    Started                                                                                                                                                       0.0s 
 ✔ Container full-cosmo-controlplane-1          Started                                                                                                                                                       0.1s 
 ✔ Container full-cosmo-seed-1                  Started                                                                                                                                                       0.0s 

$ make create-cli-demo

cd scripts && ./create-cli-demo.sh

added 344 packages in 19s

69 packages are looking for funding
  run `npm fund` for details
npm notice 
npm notice New patch version of npm available! 10.2.0 -> 10.2.5
npm notice Changelog: https://github.com/npm/cli/releases/tag/v10.2.5
npm notice Run npm install -g [email protected] to update!
npm notice 
Failed to create federated graph production.
Not authenticated
Failed to create subgraph 'employees'.
Not authenticated
Failed to create subgraph 'family'.
Not authenticated
Failed to create subgraph 'hobbies'.
Not authenticated
Failed to create subgraph 'products'.
Not authenticated
Failed to update subgraph employees.
Not authenticated
Failed to update subgraph family.
Not authenticated
Failed to update subgraph hobbies.
Not authenticated
Failed to update subgraph products.
Not authenticated
Could not create token for federated graph
Not authenticated
make: *** [create-cli-demo] Error 1

Component version

latest

Environment information

Environment

OS: macOS Sonoma 14.2
Package Manager: npm
Compiler(if manually compiled): no idea
Container Engine: podman

Router configuration

No response

Router execution config

No response

Log output

No response

Additional context

No response

test

Component(s)

router

What happened?

Description

Steps to Reproduce

Expected Result

Actual Result

Component version

323

Environment information

Environment

OS: (e.g., "Ubuntu 20.04")
Package Manager: pnpm, npm, yarn, etc
Compiler(if manually compiled): (e.g., "go 14.2")

Router configuration

No response

Router execution config

No response

Log output

No response

Additional context

No response

Problems with @override (from argument) directive and different environments

Component(s)

controlplane, studio

Is your feature request related to a problem? Please describe.

We have multiple environments and clusters, like staging productionA, productionB etc. And with Cosmo we need to define unique name for each subgraph per environment, because with each npx wgc subgraph publish command with the same name (but different labels - used for environments) it will rewrite subgraph with new labels. This is problem as we need to have single schema definition like

type Query {
  test: String! @override(from: "subgraph1")
}

But now we are forced to create names of subgraphs like subgraph1-staging, subgraph1-productionA etc. Which then makes problems as composition cannot find proper name of subgraph.

Describe the solution you'd like

Possible solution would be to be able to have same name of subgraphs for different environments like in table below.

Subgraph Routing URL Labels
subgraph1 http://subgraph1.staging.svc.local/graphql --env=staging
subgraph1 http://subgraph1.produciton.svc.local/graphql --env=production
subgraph1 http://subgraph1.production2.svc.local/graphql --env=production2

Then we could reference simply with

type Query {
  test: String! @override(from: "subgraph1")
}

Describe alternatives you've considered

No response

Additional context

No response

Possibility to run without clickhouse/jaeger/keycloak/prometheus?

I've been playing with the local cosmo setup (which works great btw!), I got a few questions/concerns/suggestions - I don't know well the product so my assumptions could be wrong:

  1. Possibility to run without clickhouse/jaeger/prometheus (e.g. if the env vars are not found the metrics/tracing page is disabled in the control panel)
    • These two are quite expensive to run for production setups
    • I'd rather delegate metrics/tracing handling to Datadog
    • Additional risk/ services to monitor: if clickhouse/jaeger/prometheus go down, then the control panel goes down as well?
  2. Possibility to run the control panel without keycloak - similarly as above if the env vars are not found then the control panel works "anonymously", could save data in LocalStorage instead
    • Keycloak also quite expensive/complicated to run for production setups
    • Additional security concern since credentials are stored
  3. My final concern is that the Go router depends on the control panel for fetching the subgraphs (maybe #61 changes that?), the control panel depends on keycloak/postgres/clickhouse/jaeger/prometheus, there's a lot of things that can go wrong scaling any of those (especially with 100x peaks) - which could potentially take down the control panel, and therefore the router?
    • For production setups, having the possibility to deploy only the router without the control panel, would be great, only one thing to scale, no external dependency

Keep up the good work!

CORS specified allowed origins not working

I'm using the router locally and I have the following cors config:

cors:
  allow_origins:
    - http://localhost:3000
    - https://localhost:3000
  allow_methods:
    - HEAD
    - GET
    - POST
  allow_headers:
    - Authorization
    - Origin
    - Content-Length
    - Content-Type
  allow_credentials: true
  max_age_minutes: 5m

But I am still getting a cors error, the response headers don't include the specified origins:
image

The request headers have the origin:
image

List of subgraphs in composition detail screen is not scrollable

Component(s)

studio

What happened?

Description

In composition detail screen having lot of subgraphs I am not able to scroll through all of them.

Screenshot 2023-12-19 at 11 19 27

Steps to Reproduce

Expected Result

Actual Result

Component version

v0.44.1

Environment information

Environment

Router configuration

No response

Router execution config

No response

Log output

No response

Additional context

No response

Name of the subgraph request

Component(s)

router

Is your feature request related to a problem? Please describe.

In the subgraph, it is not clear what kind of request came to him, I want to draw beautiful metrics

Current queries in subgraphs do not contain information about the name of the query at all

supergraph query:

query Test {
  testField
}

subgraph query:

{"query":"{testField}"}

Describe the solution you'd like

Do it like in the Apollo Rover

Requests must contain the name of the parent request and information about nesting

Query Test__service_name__3
Query Test__service_name__2
Query Test__service_name__0

Describe alternatives you've considered

No response

Additional context

No response

internal server error - could not select the datasource to resolve Query.

Component(s)

router

What happened?

Description

Registered couple of subgraphs, composition is passing, everything is green in schema registry, I can see query gearboxSettings inside, but whenever I try to query it, it will fail with internal server error.

Steps to Reproduce

Expected Result

Actual Result

500 Internal server error

Component version

0.54.2

Environment information

Environment

Router configuration

No response

Router execution config

No response

Log output

{"level":"error","time":1705525926217,"msg":"internal error","hostname":"gazelle-cosmo-8b9fb9d4c-458c9","pid":1,"component":"@wundergraph/router","service_version":"dev","reqId":"ee7c605795836b589ca21cb074f721ef","error":"1 error occurred:\n\t* nodesResolvableVisitor: could not select the datasource to resolve Query.gearboxSettings on a path query.gearboxSettings\n\n","stacktrace":"github.com/wundergraph/cosmo/router/core.logInternalErrorsFromReport\n\t/go/pkg/mod/github.com/wundergraph/cosmo/[email protected]/core/graphql_handler.go:190\ngithub.com/wundergraph/cosmo/router/core.(*PreHandler).writeOperationError\n\t/go/pkg/mod/github.com/wundergraph/cosmo/[email protected]/core/graphql_prehandler.go:213\ngithub.com/wundergraph/cosmo/router/core.(*PreHandler).Handler-fm.(*PreHandler).Handler.func1\n\t/go/pkg/mod/github.com/wundergraph/cosmo/[email protected]/core/graphql_prehandler.go:164\nnet/http.HandlerFunc.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:2136\ngithub.com/wundergraph/cosmo/router/core.(*WebsocketHandler).ServeHTTP\n\t/go/pkg/mod/github.com/wundergraph/cosmo/[email protected]/core/websocket.go:163\ngithub.com/go-chi/chi.(*Mux).ServeHTTP\n\t/go/pkg/mod/github.com/go-chi/[email protected]/mux.go:70\ngithub.com/go-chi/chi.(*Mux).Mount.func1\n\t/go/pkg/mod/github.com/go-chi/[email protected]/mux.go:311\nnet/http.HandlerFunc.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:2136\ngithub.com/go-chi/chi.(*Mux).routeHTTP\n\t/go/pkg/mod/github.com/go-chi/[email protected]/mux.go:436\nnet/http.HandlerFunc.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:2136\ngithub.com/wundergraph/cosmo/router/internal/handler/cors.(*cors).ServeHTTP\n\t/go/pkg/mod/github.com/wundergraph/cosmo/[email protected]/internal/handler/cors/config.go:96\ngithub.com/wundergraph/cosmo/router/internal/handler/requestlogger.(*handler).ServeHTTP\n\t/go/pkg/mod/github.com/wundergraph/cosmo/[email protected]/internal/handler/requestlogger/requestlogger.go:69\ngithub.com/wundergraph/cosmo/router/internal/trace.(*Middleware).Handler.func1\n\t/go/pkg/mod/github.com/wundergraph/cosmo/[email protected]/internal/trace/middleware.go:41\nnet/http.HandlerFunc.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:2136\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.(*middleware).serveHTTP\n\t/go/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/[email protected]/handler.go:229\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.NewMiddleware.func1.1\n\t/go/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/[email protected]/handler.go:81\nnet/http.HandlerFunc.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:2136\ngithub.com/go-chi/chi/middleware.RealIP.func1\n\t/go/pkg/mod/github.com/go-chi/[email protected]/middleware/realip.go:34\nnet/http.HandlerFunc.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:2136\ngithub.com/go-chi/chi/middleware.RequestID.func1\n\t/go/pkg/mod/github.com/go-chi/[email protected]/middleware/request_id.go:76\nnet/http.HandlerFunc.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:2136\ngithub.com/wundergraph/cosmo/router/internal/handler/recovery.(*handler).ServeHTTP\n\t/go/pkg/mod/github.com/wundergraph/cosmo/[email protected]/internal/handler/recovery/recovery.go:103\ngithub.com/wundergraph/cosmo/router/core.(*Router).newServer.func2.1\n\t/go/pkg/mod/github.com/wundergraph/cosmo/[email protected]/core/router.go:697\nnet/http.HandlerFunc.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:2136\ngithub.com/go-chi/chi.(*Mux).ServeHTTP\n\t/go/pkg/mod/github.com/go-chi/[email protected]/mux.go:87\nnet/http.serverHandler.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:2938\nnet/http.(*conn).serve\n\t/usr/local/go/src/net/http/server.go:2009"}

Additional context

No response

Could not plan the operation

Component(s)

router

Component version

0.69.0

wgc version

0.43.2

controlplane version

not using

router version

0.69.0

What happened?

Description

There are 2 services, todo and user. When extending the Todo type in the user service, I use the userID to look up the user for the todo. Previously, id todo was not mandatory, now it must be passed, otherwise there will be an error. I do not use id todo in the user service, but it can be used in other services, which is why it is present in @key(fields: "id, userID") in the todo service.

todo service:

type Todo @key(fields: "id, userID") {
    id: ID
    name: String!
    userID: ID!
}

user service:

type Todo @key(fields: "id, userID") {
    id: ID
    userID: ID @external
    user: User @requires(fields: "userID")
}

Warning

This is an example of a working scheme.

Steps to Reproduce

Create 2 services todo and user with the following types in the schema:
todo service:

type Todo @key(fields: "id, userID") {
    id: ID
    name: String!
    userID: ID!
}

user service:

type Todo @key(fields: "userID") {
    userID: ID @external
    user: User @requires(fields: "userID")
}

Make a request

query MyQuery {
  todoMany(pagination: {first: 10}) {
    edges {
      node {
        id
        user {
          id
          name
        }
      }
    }
  }
}

Expected Result

The query should return a todo list along with users

{
  "data": {
    "todoMany": {
      "edges": [
        {
          "node": {
            "id": "01HQJJPZWVJDSVMKC38NYW7HK5",
            "user": {
              "id": "01HQJJPRE3HM0V0724EQR3S7YA",
              "name": "test user"
            }
          }
        }
      ]
    }
  }
}

Actual Result

{
  "errors": [
    {
      "message": "internal server error"
    }
  ],
  "data": null
}

Environment information

Environment

FEDERATED_GRAPH_NAME=production
LISTEN_ADDR=0.0.0.0:3001
ROUTER_CONFIG_PATH=./config.json
METRICS_OTLP_ENABLED=false
PROMETHEUS_ENABLED=false
LOG_LEVEL=debug
DEV_MODE=true

Router configuration

version: "1"

cors:
  allow_origins: ["https://studio.apollographql.com", "http://gateway:4000", "https://localhost:4200"]
  allow_methods:
    - OPTIONS
    - GET
    - POST
  allow_headers:
    - Origin
    - Content-Length
    - Content-Type
  allow_credentials: true

telemetry:
  tracing:
    enabled: false

Router execution config

{"engineConfig":{"defaultFlushInterval":"500","datasourceConfigurations":[{"kind":"GRAPHQL","rootNodes":[{"typeName":"Query","fieldNames":["user","userMany"]},{"typeName":"Mutation","fieldNames":["createUser","updateUser","deleteUser"]},{"typeName":"Todo","fieldNames":["user","userID"]},{"typeName":"User","fieldNames":["id","name"]}],"childNodes":[{"typeName":"PageInfo","fieldNames":["endCursor","hasNextPage","hasPreviousPage","startCursor"]},{"typeName":"UserEdge","fieldNames":["cursor","node"]},{"typeName":"UserPagination","fieldNames":["edges","pageInfo","totalCount"]}],"overrideFieldPathFromAlias":true,"customGraphql":{"fetch":{"url":{"staticVariableContent":"http://localhost:8001/graphql"},"method":"POST","body":{},"baseUrl":{},"path":{}},"subscription":{"enabled":true,"url":{"staticVariableContent":"http://localhost:8001/graphql"},"protocol":"GRAPHQL_SUBSCRIPTION_PROTOCOL_WS"},"federation":{"enabled":true,"serviceSdl":"\nscalar Date\n\nenum Direction {\n  ascending\n  descending\n}\n\ntype PageInfo @shareable {\n  endCursor: String\n  hasNextPage: Boolean!\n  hasPreviousPage: Boolean!\n  startCursor: String\n}\n\nenum UserSort {\n    name\n}\n\ninput UserFilter {\n    \"\"\"Equal to name\"\"\"\n    nameEQ: String\n    \"\"\"Not equal to name\"\"\"\n    nameNEQ: String\n}\n\ninput PageArguments {\n  after: String\n  before: String\n  first: Int\n  last: Int\n}\n\ntype Todo @key(fields: \"userID\") {\n    userID: ID @external\n    user: User @requires(fields: \"userID\")\n}\n\ntype User @key(fields: \"id\") {\n    id: ID\n    name: String!\n}\n\ntype UserEdge {\n    cursor: String!\n    node: User!\n}\n\ntype UserPagination {\n    edges: [UserEdge!]!\n    pageInfo: PageInfo!\n    totalCount: Int!\n}\n\n\n\n\nextend type Query {\n    user(id: ID!): User!\n    userMany(\n        filtering: UserFilter\n        \"\"\"Sorting direction\"\"\"\n        direction: Direction\n        sortingFields: [UserSort]\n        \"\"\"List of fields by which you can search\"\"\"\n        pagination: PageArguments!\n    ): UserPagination!\n}\n\nextend type Mutation {\n    createUser(\n        name: String!\n    ): User!\n    updateUser(\n        id: ID!\n        name: String\n    ): User!\n    deleteUser(\n        \"\"\"Id user which we want to delete\"\"\"\n        id: ID!\n    ): Boolean!\n}\n"},"upstreamSchema":{"key":"22729f6159c5766d73d29ace2eb5338928e93554"}},"requestTimeoutSeconds":"10","id":"0","keys":[{"typeName":"Todo","selectionSet":"userID"},{"typeName":"User","selectionSet":"id"}],"requires":[{"typeName":"Todo","fieldName":"user","selectionSet":"userID"}]},{"kind":"GRAPHQL","rootNodes":[{"typeName":"Query","fieldNames":["todo","todoMany"]},{"typeName":"Mutation","fieldNames":["createTodo","updateTodo","deleteTodo"]},{"typeName":"Todo","fieldNames":["id","name","userID"]},{"typeName":"User","fieldNames":["todoMany","id"]}],"childNodes":[{"typeName":"PageInfo","fieldNames":["endCursor","hasNextPage","hasPreviousPage","startCursor"]},{"typeName":"TodoEdge","fieldNames":["cursor","node"]},{"typeName":"TodoPagination","fieldNames":["edges","pageInfo","totalCount"]}],"overrideFieldPathFromAlias":true,"customGraphql":{"fetch":{"url":{"staticVariableContent":"http://localhost:8002/graphql"},"method":"POST","body":{},"baseUrl":{},"path":{}},"subscription":{"enabled":true,"url":{"staticVariableContent":"http://localhost:8002/graphql"},"protocol":"GRAPHQL_SUBSCRIPTION_PROTOCOL_WS"},"federation":{"enabled":true,"serviceSdl":"\nscalar Date\n\nenum Direction {\n  ascending\n  descending\n}\n\ntype PageInfo @shareable {\n  endCursor: String\n  hasNextPage: Boolean!\n  hasPreviousPage: Boolean!\n  startCursor: String\n}\n\nenum TodoSort {\n    name\n}\n\ninput TodoFilter {\n    \"\"\"Equal to userID\"\"\"\n    userIDEQ: ID\n    \"\"\"Not equal to userID\"\"\"\n    userIDNEQ: ID\n}\n\ninput PageArguments {\n  after: String\n  before: String\n  first: Int\n  last: Int\n}\n\ntype Todo @key(fields: \"id, userID\") {\n    id: ID\n    name: String!\n    userID: ID!\n}\n\ntype User @key(fields: \"id\") {\n    id: ID @external\n    todoMany: [Todo] @requires(fields: \"id\")\n}\n\ntype TodoEdge {\n    cursor: String!\n    node: Todo!\n}\n\ntype TodoPagination {\n    edges: [TodoEdge!]!\n    pageInfo: PageInfo!\n    totalCount: Int!\n}\n\n\n\n\nextend type Query {\n    todo(id: ID!): Todo!\n    todoMany(\n        filtering: TodoFilter\n        \"\"\"Sorting direction\"\"\"\n        direction: Direction\n        sortingFields: [TodoSort]\n        \"\"\"List of fields by which you can search\"\"\"\n        pagination: PageArguments!\n    ): TodoPagination!\n}\n\nextend type Mutation {\n    createTodo(\n        name: String!\n        userID: ID!\n    ): Todo!\n    updateTodo(\n        id: ID!\n        name: String\n        userID: ID\n    ): Todo!\n    deleteTodo(\n        \"\"\"Id todo which we want to delete\"\"\"\n        id: ID!\n    ): Boolean!\n}\n"},"upstreamSchema":{"key":"1be40c74d22257537b418a7bbba875c74022beee"}},"requestTimeoutSeconds":"10","id":"1","keys":[{"typeName":"Todo","selectionSet":"id userID"},{"typeName":"User","selectionSet":"id"}],"requires":[{"typeName":"User","fieldName":"todoMany","selectionSet":"id"}]}],"fieldConfigurations":[{"typeName":"Query","fieldName":"user","argumentsConfiguration":[{"name":"id","sourceType":"FIELD_ARGUMENT"}]},{"typeName":"Query","fieldName":"userMany","argumentsConfiguration":[{"name":"filtering","sourceType":"FIELD_ARGUMENT"},{"name":"direction","sourceType":"FIELD_ARGUMENT"},{"name":"sortingFields","sourceType":"FIELD_ARGUMENT"},{"name":"pagination","sourceType":"FIELD_ARGUMENT"}]},{"typeName":"Query","fieldName":"todo","argumentsConfiguration":[{"name":"id","sourceType":"FIELD_ARGUMENT"}]},{"typeName":"Query","fieldName":"todoMany","argumentsConfiguration":[{"name":"filtering","sourceType":"FIELD_ARGUMENT"},{"name":"direction","sourceType":"FIELD_ARGUMENT"},{"name":"sortingFields","sourceType":"FIELD_ARGUMENT"},{"name":"pagination","sourceType":"FIELD_ARGUMENT"}]},{"typeName":"Mutation","fieldName":"createUser","argumentsConfiguration":[{"name":"name","sourceType":"FIELD_ARGUMENT"}]},{"typeName":"Mutation","fieldName":"updateUser","argumentsConfiguration":[{"name":"id","sourceType":"FIELD_ARGUMENT"},{"name":"name","sourceType":"FIELD_ARGUMENT"}]},{"typeName":"Mutation","fieldName":"deleteUser","argumentsConfiguration":[{"name":"id","sourceType":"FIELD_ARGUMENT"}]},{"typeName":"Mutation","fieldName":"createTodo","argumentsConfiguration":[{"name":"name","sourceType":"FIELD_ARGUMENT"},{"name":"userID","sourceType":"FIELD_ARGUMENT"}]},{"typeName":"Mutation","fieldName":"updateTodo","argumentsConfiguration":[{"name":"id","sourceType":"FIELD_ARGUMENT"},{"name":"name","sourceType":"FIELD_ARGUMENT"},{"name":"userID","sourceType":"FIELD_ARGUMENT"}]},{"typeName":"Mutation","fieldName":"deleteTodo","argumentsConfiguration":[{"name":"id","sourceType":"FIELD_ARGUMENT"}]}],"graphqlSchema":"directive @tag(name: String!) repeatable on ARGUMENT_DEFINITION | ENUM | ENUM_VALUE | FIELD_DEFINITION | INPUT_FIELD_DEFINITION | INPUT_OBJECT | INTERFACE | OBJECT | SCALAR | UNION\n\ndirective @authenticated on ENUM | FIELD_DEFINITION | INTERFACE | OBJECT | SCALAR\n\ndirective @inaccessible on ARGUMENT_DEFINITION | ENUM | ENUM_VALUE | FIELD_DEFINITION | INPUT_FIELD_DEFINITION | INPUT_OBJECT | INTERFACE | OBJECT | SCALAR | UNION\n\ndirective @requiresScopes(scopes: [[openfed__Scope!]!]!) on ENUM | FIELD_DEFINITION | INTERFACE | OBJECT | SCALAR\n\nscalar openfed__Scope\n\nscalar Date\n\nenum Direction {\n  ascending\n  descending\n}\n\ntype PageInfo {\n  endCursor: String\n  hasNextPage: Boolean!\n  hasPreviousPage: Boolean!\n  startCursor: String\n}\n\nenum UserSort {\n  name\n}\n\ninput UserFilter {\n  \"\"\"Equal to name\"\"\"\n  nameEQ: String\n\n  \"\"\"Not equal to name\"\"\"\n  nameNEQ: String\n}\n\ninput PageArguments {\n  after: String\n  before: String\n  first: Int\n  last: Int\n}\n\ntype Todo {\n  userID: ID\n  user: User\n  id: ID\n  name: String!\n}\n\ntype User {\n  id: ID\n  name: String!\n  todoMany: [Todo]\n}\n\ntype UserEdge {\n  cursor: String!\n  node: User!\n}\n\ntype UserPagination {\n  edges: [UserEdge!]!\n  pageInfo: PageInfo!\n  totalCount: Int!\n}\n\nenum TodoSort {\n  name\n}\n\ninput TodoFilter {\n  \"\"\"Equal to userID\"\"\"\n  userIDEQ: ID\n\n  \"\"\"Not equal to userID\"\"\"\n  userIDNEQ: ID\n}\n\ntype TodoEdge {\n  cursor: String!\n  node: Todo!\n}\n\ntype TodoPagination {\n  edges: [TodoEdge!]!\n  pageInfo: PageInfo!\n  totalCount: Int!\n}\n\ntype Query {\n  user(id: ID!): User!\n  userMany(\n    filtering: UserFilter\n\n    \"\"\"Sorting direction\"\"\"\n    direction: Direction\n    sortingFields: [UserSort]\n\n    \"\"\"List of fields by which you can search\"\"\"\n    pagination: PageArguments!\n  ): UserPagination!\n  todo(id: ID!): Todo!\n  todoMany(\n    filtering: TodoFilter\n\n    \"\"\"Sorting direction\"\"\"\n    direction: Direction\n    sortingFields: [TodoSort]\n\n    \"\"\"List of fields by which you can search\"\"\"\n    pagination: PageArguments!\n  ): TodoPagination!\n}\n\ntype Mutation {\n  createUser(name: String!): User!\n  updateUser(id: ID!, name: String): User!\n  deleteUser(\n    \"\"\"Id user which we want to delete\"\"\"\n    id: ID!\n  ): Boolean!\n  createTodo(name: String!, userID: ID!): Todo!\n  updateTodo(id: ID!, name: String, userID: ID): Todo!\n  deleteTodo(\n    \"\"\"Id todo which we want to delete\"\"\"\n    id: ID!\n  ): Boolean!\n}","stringStorage":{"22729f6159c5766d73d29ace2eb5338928e93554":"schema {\n  query: Query\n  mutation: Mutation\n}\n\ndirective @authenticated on ENUM | FIELD_DEFINITION | INTERFACE | OBJECT | SCALAR\n\ndirective @composeDirective(name: String!) repeatable on SCHEMA\n\ndirective @eventsPublish(sourceID: String, topic: String!) on FIELD_DEFINITION\n\ndirective @eventsRequest(sourceID: String, topic: String!) on FIELD_DEFINITION\n\ndirective @eventsSubscribe(sourceID: String, topic: String!) on FIELD_DEFINITION\n\ndirective @extends on INTERFACE | OBJECT\n\ndirective @external on FIELD_DEFINITION | OBJECT\n\ndirective @inaccessible on ARGUMENT_DEFINITION | ENUM | ENUM_VALUE | FIELD_DEFINITION | INPUT_FIELD_DEFINITION | INPUT_OBJECT | INTERFACE | OBJECT | SCALAR | UNION\n\ndirective @interfaceObject on OBJECT\n\ndirective @key(fields: openfed__FieldSet!, resolvable: Boolean = true) repeatable on INTERFACE | OBJECT\n\ndirective @link(as: String, for: String, import: [String], url: String!) repeatable on SCHEMA\n\ndirective @override(from: String!) on FIELD_DEFINITION\n\ndirective @provides(fields: openfed__FieldSet!) on FIELD_DEFINITION\n\ndirective @requires(fields: openfed__FieldSet!) on FIELD_DEFINITION\n\ndirective @requiresScopes(scopes: [[openfed__Scope!]!]!) on ENUM | FIELD_DEFINITION | INTERFACE | OBJECT | SCALAR\n\ndirective @shareable on FIELD_DEFINITION | OBJECT\n\ndirective @tag(name: String!) repeatable on ARGUMENT_DEFINITION | ENUM | ENUM_VALUE | FIELD_DEFINITION | INPUT_FIELD_DEFINITION | INPUT_OBJECT | INTERFACE | OBJECT | SCALAR | UNION\n\nscalar Date\n\nenum Direction {\n  ascending\n  descending\n}\n\ntype Mutation {\n  createUser(name: String!): User!\n  deleteUser(\n    \"\"\"Id user which we want to delete\"\"\"\n    id: ID!\n  ): Boolean!\n  updateUser(id: ID!, name: String): User!\n}\n\ninput PageArguments {\n  after: String\n  before: String\n  first: Int\n  last: Int\n}\n\ntype PageInfo {\n  endCursor: String @shareable\n  hasNextPage: Boolean! @shareable\n  hasPreviousPage: Boolean! @shareable\n  startCursor: String @shareable\n}\n\ntype Query {\n  user(id: ID!): User!\n  userMany(\n    \"\"\"Sorting direction\"\"\"\n    direction: Direction\n    filtering: UserFilter\n    \"\"\"List of fields by which you can search\"\"\"\n    pagination: PageArguments!\n    sortingFields: [UserSort]\n  ): UserPagination!\n}\n\ntype Todo @key(fields: \"userID\") {\n  user: User @requires(fields: \"userID\")\n  userID: ID @external\n}\n\ntype User @key(fields: \"id\") {\n  id: ID\n  name: String!\n}\n\ntype UserEdge {\n  cursor: String!\n  node: User!\n}\n\ninput UserFilter {\n  \"\"\"Equal to name\"\"\"\n  nameEQ: String\n  \"\"\"Not equal to name\"\"\"\n  nameNEQ: String\n}\n\ntype UserPagination {\n  edges: [UserEdge!]!\n  pageInfo: PageInfo!\n  totalCount: Int!\n}\n\nenum UserSort {\n  name\n}\n\nscalar openfed__FieldSet\n\nscalar openfed__Scope","1be40c74d22257537b418a7bbba875c74022beee":"schema {\n  query: Query\n  mutation: Mutation\n}\n\ndirective @authenticated on ENUM | FIELD_DEFINITION | INTERFACE | OBJECT | SCALAR\n\ndirective @composeDirective(name: String!) repeatable on SCHEMA\n\ndirective @eventsPublish(sourceID: String, topic: String!) on FIELD_DEFINITION\n\ndirective @eventsRequest(sourceID: String, topic: String!) on FIELD_DEFINITION\n\ndirective @eventsSubscribe(sourceID: String, topic: String!) on FIELD_DEFINITION\n\ndirective @extends on INTERFACE | OBJECT\n\ndirective @external on FIELD_DEFINITION | OBJECT\n\ndirective @inaccessible on ARGUMENT_DEFINITION | ENUM | ENUM_VALUE | FIELD_DEFINITION | INPUT_FIELD_DEFINITION | INPUT_OBJECT | INTERFACE | OBJECT | SCALAR | UNION\n\ndirective @interfaceObject on OBJECT\n\ndirective @key(fields: openfed__FieldSet!, resolvable: Boolean = true) repeatable on INTERFACE | OBJECT\n\ndirective @link(as: String, for: String, import: [String], url: String!) repeatable on SCHEMA\n\ndirective @override(from: String!) on FIELD_DEFINITION\n\ndirective @provides(fields: openfed__FieldSet!) on FIELD_DEFINITION\n\ndirective @requires(fields: openfed__FieldSet!) on FIELD_DEFINITION\n\ndirective @requiresScopes(scopes: [[openfed__Scope!]!]!) on ENUM | FIELD_DEFINITION | INTERFACE | OBJECT | SCALAR\n\ndirective @shareable on FIELD_DEFINITION | OBJECT\n\ndirective @tag(name: String!) repeatable on ARGUMENT_DEFINITION | ENUM | ENUM_VALUE | FIELD_DEFINITION | INPUT_FIELD_DEFINITION | INPUT_OBJECT | INTERFACE | OBJECT | SCALAR | UNION\n\nscalar Date\n\nenum Direction {\n  ascending\n  descending\n}\n\ntype Mutation {\n  createTodo(name: String!, userID: ID!): Todo!\n  deleteTodo(\n    \"\"\"Id todo which we want to delete\"\"\"\n    id: ID!\n  ): Boolean!\n  updateTodo(id: ID!, name: String, userID: ID): Todo!\n}\n\ninput PageArguments {\n  after: String\n  before: String\n  first: Int\n  last: Int\n}\n\ntype PageInfo {\n  endCursor: String @shareable\n  hasNextPage: Boolean! @shareable\n  hasPreviousPage: Boolean! @shareable\n  startCursor: String @shareable\n}\n\ntype Query {\n  todo(id: ID!): Todo!\n  todoMany(\n    \"\"\"Sorting direction\"\"\"\n    direction: Direction\n    filtering: TodoFilter\n    \"\"\"List of fields by which you can search\"\"\"\n    pagination: PageArguments!\n    sortingFields: [TodoSort]\n  ): TodoPagination!\n}\n\ntype Todo @key(fields: \"id, userID\") {\n  id: ID\n  name: String!\n  userID: ID!\n}\n\ntype TodoEdge {\n  cursor: String!\n  node: Todo!\n}\n\ninput TodoFilter {\n  \"\"\"Equal to userID\"\"\"\n  userIDEQ: ID\n  \"\"\"Not equal to userID\"\"\"\n  userIDNEQ: ID\n}\n\ntype TodoPagination {\n  edges: [TodoEdge!]!\n  pageInfo: PageInfo!\n  totalCount: Int!\n}\n\nenum TodoSort {\n  name\n}\n\ntype User @key(fields: \"id\") {\n  id: ID @external\n  todoMany: [Todo] @requires(fields: \"id\")\n}\n\nscalar openfed__FieldSet\n\nscalar openfed__Scope"}},"subgraphs":[{"id":"0","name":"user","routingUrl":"http://localhost:8001/graphql"},{"id":"1","name":"todo","routingUrl":"http://localhost:8002/graphql"}]}

Log output

12:06:40 PM INFO cmd/main.go:62 Found default config file. Values in the config file have higher priority than environment variables {"component": "@wundergraph/router", "service_version": "0.69.0", "config_file": "config.yaml"}
12:06:40 PM DEBUG maxprocs/maxprocs.go:47 maxprocs: Leaving GOMAXPROCS=10: CPU quota undefined {"component": "@wundergraph/router", "service_version": "0.69.0"}
12:06:40 PM WARN core/router.go:364 No graph token provided. The following features are disabled. Not recommended for Production. {"component": "@wundergraph/router", "service_version": "0.69.0", "features": ["Schema Usage Tracking", "Persistent operations"]}
12:06:40 PM WARN core/router.go:379 Development mode enabled. This should only be used for testing purposes {"component": "@wundergraph/router", "service_version": "0.69.0"}
12:06:40 PM INFO core/router.go:711 Static router config provided. Polling is disabled. Updating router config is only possible by providing a config. {"component": "@wundergraph/router", "service_version": "0.69.0"}
12:06:40 PM WARN core/router.go:949 Advanced Request Tracing (ART) is enabled in development mode but requires a graph token to work in production. For more information see https://cosmo-docs.wundergraph.com/router/advanced-request-tracing-art {"component": "@wundergraph/router", "service_version": "0.69.0"}
12:06:40 PM INFO core/router.go:983 Serving GraphQL playground {"component": "@wundergraph/router", "service_version": "0.69.0", "url": "http://0.0.0.0:3001/"}
12:06:40 PM INFO core/router.go:1030 Rate limiting disabled {"component": "@wundergraph/router", "service_version": "0.69.0"}
12:06:40 PM INFO core/router.go:1113 GraphQL endpoint {"component": "@wundergraph/router", "service_version": "0.69.0", "method": "POST", "url": "http://0.0.0.0:3001/graphql"}
12:06:40 PM INFO core/router.go:469 Server listening {"component": "@wundergraph/router", "service_version": "0.69.0", "listen_addr": "0.0.0.0:3001", "playground": true, "introspection": true, "config_version": ""}
12:06:46 PM ERROR core/graphql_prehandler.go:292 failed to plan operation {"component": "@wundergraph/router", "service_version": "0.69.0", "reqId": "MBP-Rost.fritz.box/cDly8hYaIk-000001", "error": "bad datasource configuration - could not plan the operation"}
github.com/wundergraph/cosmo/router/core.(*PreHandler).Handler-fm.(*PreHandler).Handler.func1
	github.com/wundergraph/cosmo/router/core/graphql_prehandler.go:292
net/http.HandlerFunc.ServeHTTP
	net/http/server.go:2166
github.com/wundergraph/cosmo/router/core.(*WebsocketHandler).ServeHTTP
	github.com/wundergraph/cosmo/router/core/websocket.go:176
github.com/go-chi/chi/v5.(*Mux).ServeHTTP
	github.com/go-chi/chi/[email protected]/mux.go:73
github.com/go-chi/chi/v5.(*Mux).Mount.func1
	github.com/go-chi/chi/[email protected]/mux.go:315
net/http.HandlerFunc.ServeHTTP
	net/http/server.go:2166
github.com/go-chi/chi/v5.(*Mux).routeHTTP
	github.com/go-chi/chi/[email protected]/mux.go:443
net/http.HandlerFunc.ServeHTTP
	net/http/server.go:2166
github.com/wundergraph/cosmo/router/pkg/cors.(*cors).ServeHTTP
	github.com/wundergraph/cosmo/router/pkg/cors/config.go:74
github.com/wundergraph/cosmo/router/internal/requestlogger.(*handler).ServeHTTP
	github.com/wundergraph/cosmo/router/internal/requestlogger/requestlogger.go:99
github.com/go-chi/chi/v5/middleware.RealIP.func1
	github.com/go-chi/chi/[email protected]/middleware/realip.go:36
net/http.HandlerFunc.ServeHTTP
	net/http/server.go:2166
github.com/go-chi/chi/v5/middleware.RequestID.func1
	github.com/go-chi/chi/[email protected]/middleware/request_id.go:76
net/http.HandlerFunc.ServeHTTP
	net/http/server.go:2166
github.com/wundergraph/cosmo/router/internal/recoveryhandler.(*handler).ServeHTTP
	github.com/wundergraph/cosmo/router/internal/recoveryhandler/recovery.go:103
github.com/wundergraph/cosmo/router/core.(*Router).newServer.func2.1
	github.com/wundergraph/cosmo/router/core/router.go:836
net/http.HandlerFunc.ServeHTTP
	net/http/server.go:2166
github.com/go-chi/chi/v5.(*Mux).ServeHTTP
	github.com/go-chi/chi/[email protected]/mux.go:90
net/http.serverHandler.ServeHTTP
	net/http/server.go:3137
net/http.(*conn).serve
	net/http/server.go:2039
12:06:46 PM ERROR core/graphql_handler.go:357 internal error {"component": "@wundergraph/router", "service_version": "0.69.0", "reqId": "MBP-Rost.fritz.box/cDly8hYaIk-000001", "error": "1 error occurred:\n\t* bad datasource configuration - could not plan the operation\n\n"}
github.com/wundergraph/cosmo/router/core.logInternalErrorsFromReport
	github.com/wundergraph/cosmo/router/core/graphql_handler.go:357
github.com/wundergraph/cosmo/router/core.(*PreHandler).writeOperationError
	github.com/wundergraph/cosmo/router/core/graphql_prehandler.go:418
github.com/wundergraph/cosmo/router/core.(*PreHandler).Handler-fm.(*PreHandler).Handler.func1
	github.com/wundergraph/cosmo/router/core/graphql_prehandler.go:293
net/http.HandlerFunc.ServeHTTP
	net/http/server.go:2166
github.com/wundergraph/cosmo/router/core.(*WebsocketHandler).ServeHTTP
	github.com/wundergraph/cosmo/router/core/websocket.go:176
github.com/go-chi/chi/v5.(*Mux).ServeHTTP
	github.com/go-chi/chi/[email protected]/mux.go:73
github.com/go-chi/chi/v5.(*Mux).Mount.func1
	github.com/go-chi/chi/[email protected]/mux.go:315
net/http.HandlerFunc.ServeHTTP
	net/http/server.go:2166
github.com/go-chi/chi/v5.(*Mux).routeHTTP
	github.com/go-chi/chi/[email protected]/mux.go:443
net/http.HandlerFunc.ServeHTTP
	net/http/server.go:2166
github.com/wundergraph/cosmo/router/pkg/cors.(*cors).ServeHTTP
	github.com/wundergraph/cosmo/router/pkg/cors/config.go:74
github.com/wundergraph/cosmo/router/internal/requestlogger.(*handler).ServeHTTP
	github.com/wundergraph/cosmo/router/internal/requestlogger/requestlogger.go:99
github.com/go-chi/chi/v5/middleware.RealIP.func1
	github.com/go-chi/chi/[email protected]/middleware/realip.go:36
net/http.HandlerFunc.ServeHTTP
	net/http/server.go:2166
github.com/go-chi/chi/v5/middleware.RequestID.func1
	github.com/go-chi/chi/[email protected]/middleware/request_id.go:76
net/http.HandlerFunc.ServeHTTP
	net/http/server.go:2166
github.com/wundergraph/cosmo/router/internal/recoveryhandler.(*handler).ServeHTTP
	github.com/wundergraph/cosmo/router/internal/recoveryhandler/recovery.go:103
github.com/wundergraph/cosmo/router/core.(*Router).newServer.func2.1
	github.com/wundergraph/cosmo/router/core/router.go:836
net/http.HandlerFunc.ServeHTTP
	net/http/server.go:2166
github.com/go-chi/chi/v5.(*Mux).ServeHTTP
	github.com/go-chi/chi/[email protected]/mux.go:90
net/http.serverHandler.ServeHTTP
	net/http/server.go:3137
net/http.(*conn).serve
	net/http/server.go:2039
12:06:46 PM INFO requestlogger/requestlogger.go:143 /graphql {"component": "@wundergraph/router", "service_version": "0.69.0", "status": 500, "method": "POST", "path": "/graphql", "query": "", "ip": "[REDACTED]", "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2.1 Safari/605.1.15", "latency": 0.017435916, "config_version": "", "request_id": "MBP-Rost.fritz.box/cDly8hYaIk-000001"}

Additional context

No response

Difference between Cosmo and BFF Framework

Component(s)

router

Is your feature request related to a problem? Please describe.

Hi,

Thank you for that good project.

We are working on multiple graphql backs and I was looking for a solution too use with our React/Relay front.
I have tried Cosmo which is working nice for now but I have some difficulties to understand the true difference between Cosmo and BFF Framework. Cosmo make the job but I could be interested in getting REST and databases ressources.

I search all the website and the only "clear" information I found is on the blog https://wundergraph.com/blog/graphql-is-finally-boring#wundergraph-gateway which didn't really help me because I understand "if you need that project, use that project... ok..." :).

I'm not sure but perhaps BFF is more "open" to federate others sources like REST, databases... I thought Cosmo could do that before but I didn't find information in documentation (only graphql I think).

I found that tutorial https://cosmo-docs.wundergraph.com/tutorial/composing-graphs which make me think that BFF was perhaps used by cosmo (because in cosmo doc) but nothing on how to use it with the router.... Perhaps do we have to convert it in GO with custom modules...

Thank you for all and sorry if I miss something somewhere...

Describe the solution you'd like

Explain on the website or into the doc what is the true scope of each project and how to use both eventually.

Describe alternatives you've considered

No response

Additional context

No response

Cannot start cosmo following readme instructions

So when i tried running

make full-demo-up

I ran into some file permission issues which i solved by adding permissions under docker file sharing

but now i get this

❯ make full-demo-up
docker compose -f docker-compose.full.yml --profile default up --build --remove-orphans --detach
WARN[0000] The "OTEL_AUTH_TOKEN" variable is not set. Defaulting to a blank string.
WARN[0000] The "OTEL_AUTH_TOKEN" variable is not set. Defaulting to a blank string.
WARN[0000] The "OTEL_AUTH_TOKEN" variable is not set. Defaulting to a blank string.
WARN[0000] The "OTEL_AUTH_TOKEN" variable is not set. Defaulting to a blank string.
WARN[0000] The "ROUTER_TOKEN" variable is not set. Defaulting to a blank string.
[+] Running 15/15
 ✔ Network primary                              Created                                                                                                                             0.0s
 ✔ Network full-cosmo_default                   Created                                                                                                                             0.0s
 ✔ Volume "full-cosmo_clickhouse"               Created                                                                                                                             0.0s
 ✔ Volume "full-cosmo_postgres"                 Created                                                                                                                             0.0s
 ✔ Volume "full-cosmo_prometheus"               Created                                                                                                                             0.0s
 ✔ Container full-cosmo-studio-1                Started                                                                                                                             0.0s
 ✔ Container full-cosmo-prometheus-1            Created                                                                                                                             0.0s
 ✔ Container full-cosmo-clickhouse-1            Started                                                                                                                             0.0s
 ✔ Container full-cosmo-postgres-1              Started                                                                                                                             0.0s
 ✔ Container full-cosmo-otelcollector-1         Created                                                                                                                             0.0s
 ✔ Container full-cosmo-clickhouse-migration-1  Created                                                                                                                             0.0s
 ✔ Container full-cosmo-database-migration-1    Created                                                                                                                             0.0s
 ✔ Container full-cosmo-keycloak-1              Created                                                                                                                             0.0s
 ✔ Container full-cosmo-controlplane-1          Created                                                                                                                             0.0s
 ✔ Container full-cosmo-seed-1                  Created                                                                                                                             0.0s
Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error mounting "/host_mnt/opt/jagundi/cosmo/docker/prometheus/prometheus.yml" to rootfs at "/etc/prometheus/prometheus.yml": mount /host_mnt/opt/jagundi/cosmo/docker/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml (via /proc/self/fd/9), flags: 0x5000: not a directory: unknown: Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type
make: *** [full-demo-up] Error 1
image

controlplane db migration: DB::Exception: Table cosmo.operation_request_metrics_5_30_mv does not exist

Component(s)

controlplane

Component version

ghcr.io/wundergraph/cosmo/controlplane@sha256:b226292a8fddcd4cb51c6be03ccefb62d111c7b01a78922cc7054531ba1a0f0e

wgc version

n/a

controlplane version

image sha256:b226292a8fddcd4cb51c6be03ccefb62d111c7b01a78922cc7054531ba1a0f0e

router version

n/a

What happened?

If possible, please create a PR with a failing test to illustrate the issue clearly.

Otherwise, please attach a minimum reproduction through a GitHub repository that includes

essential information such as the relevant subgraph SDLs.

Please also make sure that the instructions for the reproduction are clear, tested, and fully accurate.

Description

After solving creation of DB #566 with #567 it appears that database migration doesn't work and later in the flow when trying to fetch graphs I'm getting an error in clickhouse:

2024.02.22 17:11:04.884503 [ 333 ] {b32294f0-ee70-4058-af7d-9d0bd0a032a2} <Error> DynamicQueryHandler: Code: 60. DB::Exc
eption: Table cosmo.operation_request_metrics_5_30_mv does not exist. (UNKNOWN_TABLE), Stack trace (when copying this me
ssage, always include the lines below):

0. DB::Exception::Exception(DB::Exception::MessageMasked&&, int, bool) @ 0x000000000c630397 in /opt/bitnami/clickhouse/b
in/clickhouse
1. DB::Exception::Exception<String, String>(int, FormatStringHelperImpl<std::type_identity<String>::type, std::type_iden
tity<String>::type>, String&&, String&&) @ 0x00000000071433e7 in /opt/bitnami/clickhouse/bin/clickhouse
2. DB::IDatabase::getTable(String const&, std::shared_ptr<DB::Context const>) const @ 0x00000000114bb6b9 in /opt/bitnami
/clickhouse/bin/clickhouse
3. DB::DatabaseCatalog::getTableImpl(DB::StorageID const&, std::shared_ptr<DB::Context const>, std::optional<DB::Excepti
on>*) const @ 0x00000000116ea2a8 in /opt/bitnami/clickhouse/bin/clickhouse
4. DB::DatabaseCatalog::getTable(DB::StorageID const&, std::shared_ptr<DB::Context const>) const @ 0x00000000116f3a49 in
 /opt/bitnami/clickhouse/bin/clickhouse
5. DB::JoinedTables::getLeftTableStorage() @ 0x0000000011fc30d4 in /opt/bitnami/clickhouse/bin/clickhouse
6. DB::InterpreterSelectQuery::InterpreterSelectQuery(std::shared_ptr<DB::IAST> const&, std::shared_ptr<DB::Context> con
st&, std::optional<DB::Pipe>, std::shared_ptr<DB::IStorage> const&, DB::SelectQueryOptions const&, std::vector<String, s
td::allocator<String>> const&, std::shared_ptr<DB::StorageInMemoryMetadata const> const&, std::shared_ptr<DB::PreparedSe
ts>) @ 0x0000000011ecdc43 in /opt/bitnami/clickhouse/bin/clickhouse
7. DB::InterpreterSelectWithUnionQuery::InterpreterSelectWithUnionQuery(std::shared_ptr<DB::IAST> const&, std::shared_pt
r<DB::Context>, DB::SelectQueryOptions const&, std::vector<String, std::allocator<String>> const&) @ 0x0000000011f80c68
in /opt/bitnami/clickhouse/bin/clickhouse
8. DB::InterpreterSelectWithUnionQuery::getSampleBlock(std::shared_ptr<DB::IAST> const&, std::shared_ptr<DB::Context con
st>, bool, bool) @ 0x0000000011f84337 in /opt/bitnami/clickhouse/bin/clickhouse
9. DB::getDatabaseAndTablesWithColumns(std::vector<DB::ASTTableExpression const*, std::allocator<DB::ASTTableExpression
const*>> const&, std::shared_ptr<DB::Context const>, bool, bool, bool) @ 0x00000000122dd44d in /opt/bitnami/clickhouse/b
in/clickhouse
10. DB::JoinedTables::resolveTables() @ 0x0000000011fc338d in /opt/bitnami/clickhouse/bin/clickhouse
11. DB::InterpreterSelectQuery::InterpreterSelectQuery(std::shared_ptr<DB::IAST> const&, std::shared_ptr<DB::Context> co
nst&, std::optional<DB::Pipe>, std::shared_ptr<DB::IStorage> const&, DB::SelectQueryOptions const&, std::vector<String,
std::allocator<String>> const&, std::shared_ptr<DB::StorageInMemoryMetadata const> const&, std::shared_ptr<DB::PreparedS
ets>) @ 0x0000000011ece227 in /opt/bitnami/clickhouse/bin/clickhouse
12. DB::InterpreterSelectWithUnionQuery::InterpreterSelectWithUnionQuery(std::shared_ptr<DB::IAST> const&, std::shared_p
tr<DB::Context>, DB::SelectQueryOptions const&, std::vector<String, std::allocator<String>> const&) @ 0x0000000011f80c68
 in /opt/bitnami/clickhouse/bin/clickhouse
13. DB::InterpreterFactory::get(std::shared_ptr<DB::IAST>&, std::shared_ptr<DB::Context>, DB::SelectQueryOptions const&)
 @ 0x0000000011e87c7e in /opt/bitnami/clickhouse/bin/clickhouse
14. DB::executeQueryImpl(char const*, char const*, std::shared_ptr<DB::Context>, bool, DB::QueryProcessingStage::Enum, D
B::ReadBuffer*) @ 0x00000000122ca06a in /opt/bitnami/clickhouse/bin/clickhouse
15. DB::executeQuery(DB::ReadBuffer&, DB::WriteBuffer&, bool, std::shared_ptr<DB::Context>, std::function<void (DB::Quer
yResultDetails const&)>, std::optional<DB::FormatSettings> const&) @ 0x00000000122cd711 in /opt/bitnami/clickhouse/bin/c
lickhouse
16. DB::HTTPHandler::processQuery(DB::HTTPServerRequest&, DB::HTMLForm&, DB::HTTPServerResponse&, DB::HTTPHandler::Outpu
t&, std::optional<DB::CurrentThread::QueryScope>&) @ 0x00000000130ddaef in /opt/bitnami/clickhouse/bin/clickhouse
17. DB::HTTPHandler::handleRequest(DB::HTTPServerRequest&, DB::HTTPServerResponse&) @ 0x00000000130e23c9 in /opt/bitnami
/clickhouse/bin/clickhouse
18. DB::HTTPServerConnection::run() @ 0x0000000013153072 in /opt/bitnami/clickhouse/bin/clickhouse
19. Poco::Net::TCPServerConnection::start() @ 0x0000000015b3b9d4 in /opt/bitnami/clickhouse/bin/clickhouse
20. Poco::Net::TCPServerDispatcher::run() @ 0x0000000015b3cbd1 in /opt/bitnami/clickhouse/bin/clickhouse
21. Poco::PooledThread::run() @ 0x0000000015c73407 in /opt/bitnami/clickhouse/bin/clickhouse
22. 21. Poco::PooledThread::run() @ 0x0000000015c73407 in /opt/bitnami/clickhouse/bin/clickhouse
22. Poco::ThreadImpl::runnableEntry(void*) @ 0x0000000015c716dc in /opt/bitnami/clickhouse/bin/clickhouse
23. start_thread @ 0x0000000000007ea7 in /lib/x86_64-linux-gnu/libpthread-2.31.so
24. ? @ 0x00000000000fba2f in /lib/x86_64-linux-gnu/libc-2.31.so
 (version 23.8.3.48 (official build))
2024.02.22 17:11:07.923709 [ 333 ] {52f398cb-1c6a-402e-bb23-1f56352f7bf5} <Error> executeQuery: Code: 60. DB::Exception:
 Table cosmo.operation_request_metrics_5_30_mv does not exist. (UNKNOWN_TABLE) (version 23.8.3.48 (official build)) (fro
m 10.115.19.137:50788) (in query:  WITH toStartOfInterval(toDateTime('1708607467'), INTERVAL 5 MINUTE) AS startDate, toD
ateTime('1708621867') AS endDate SELECT toString(toUnixTimestamp(timestamp, 'UTC') * 1000) as timestamp, totalRequests,
erroredRequests FROM ( SELECT toStartOfInterval(Timestamp, INTERVAL 5 MINUTE) AS timestamp, sum(TotalRequests) as totalR
equests, sum(TotalErrors) as erroredRequests FROM cosmo.operation_request_metrics_5_30_mv WHERE timestamp >= startDate A
ND timestamp <= endDate AND FederatedGraphID = 'bf51383f-62f5-4d35-8832-af6d6245f9a6' AND OrganizationID = '6b422fd3-749
0-49db-9b3d-5d84a5fb4bff' GROUP BY timestamp ORDER BY timestamp WITH FILL FROM toStartOfInterval(toDateTime('1708607467'
), INTERVAL 5 MINUTE) TO toDateTime('1708621867') STEP INTERVAL 5 MINUTE ) FORMAT JSON), Stack trace (when copying this
message, always include the lines below):

Steps to Reproduce

  1. follow steps in helm/cosmo/README.md

Expected Result

Actual Result

Environment information

Environment

OS: (e.g., "Ubuntu 20.04")
Package Manager: pnpm, npm, yarn, etc
Compiler(if manually compiled): (e.g., "go 14.2")

Router configuration

No response

Router execution config

No response

Log output

No response

Additional context

No response

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.