tailcall icon indicating copy to clipboard operation
tailcall copied to clipboard

Type checking for GraphQL composition

Open mayant15 opened this issue 2 years ago • 3 comments

Is your feature request related to a problem? Please describe. This is an invalid schema, wrongNode is marked as returning a User but the resolver makes a call to posts, which doesn't return User. This instead fails at run time.

type Query {
  posts: [Post] @http(path: "/posts")
  wrongNode: User @graphQL(name: "posts")
}

Error:

{
  "data": null,
  "errors": [
    {
      "message": "IOException: Request error: HTTP status client error (404 Not Found) for url (http://jsonplaceholder.typicode.com/)",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ]
    }
  ]
}

Describe the solution you'd like tc check should perform some type checking to avoid these issues. Maybe add type checks to validate_field_has_resolver as well. https://github.com/tailcallhq/tailcall/blob/5c479a955b06e654e46f145403c91fb4a0c48db2/src/blueprint/from_config/schema.rs#L32

mayant15 avatar Dec 17 '23 04:12 mayant15

Indeed, right now tailcall only relies on the defined schema in the config about the shape of data. In case the schema and the upstream are not the same we consider it as a configuration problem. Anyway, validation on schema may improve developer experience, and we are thinking about it.

That could be solved with different approaches:

  • add introspection validation for graphql queries on config validation.
  • add command to generate composed config for graphql upstream. That way config may diverge with time, but regeneration should update it

meskill avatar Dec 25 '23 10:12 meskill

Let's say a client sends a request to Server A (running Tailcall). To be able to serve this request Server A needs to make a GQL request to Server B. The config we run Tailcall with defines the schema between client and A, but we currently have to means of specifying the schema between A and B. Typechecking on A's config requires this schema.

There are two ways around this:

  1. Send an introspection query to B to get the latest schema, then validate A's config
  2. Simply ask A's developers to define the schema between A and B as well

As a quick POC I implemented the second option, but can be replaced by the first as well.

mayant15 avatar Dec 29 '23 21:12 mayant15

I don't think that the approach 2 is very useful due to fact that this is almost like defining schema 2 times for tailcall and upstream that should satisfy each other and in case in any mistakes inside definitions we'll get a runtime error. In that case use only one schema definition as for now is ok since anyway it's the user responsibility to provide right schema.

And the approach 1 is indeed very useful for user experience as it'll check the schema with actual upstreams schemas minimizing possible errors. We should explore this approach and how it could be implemented for REST upstream. For grpc, for example, we leverage type checks from protobuf definitions so it's good already

meskill avatar Jan 02 '24 10:01 meskill

Action required: Issue inactive for 30 days. Status update or closure in 7 days.

github-actions[bot] avatar Feb 02 '24 16:02 github-actions[bot]

Issue closed after 7 days of inactivity.

github-actions[bot] avatar Feb 09 '24 16:02 github-actions[bot]