apollographql / apollo-rs

Spec compliant GraphQL Tools in Rust.
Apache License 2.0
566 stars 41 forks source link

Consider resolving root __typename as schema introspection #867

Open yanns opened 2 months ago

yanns commented 2 months ago

Description

SchemaIntrospectionQuery::split_and_execute cannot solve the query { __typename }

Steps to reproduce

I'm playing with the introspection with a code similiar to https://github.com/apollographql/apollo-rs/pull/859/files

When I use a query like { __schema { types { name } } }, everything is working fine. When I use the query { __typename }, the execute_non_introspection_parts function is being called.

Expected result

SchemaIntrospectionQuery::split_and_execute should solve the query { __typename } and return the following:

{
  "data": {
    "__typename": "Query"
  }
}

Actual result

The code panic as the following function is being called:

|_| panic!("Provided query must not have non-introspection elements")

https://github.com/apollographql/apollo-rs/pull/859/files#diff-6416f1ff6c1a61aa6817f3430bcde09ca29f1fdb819603a5058d7991a33adfd1R42

Environment

SimonSapin commented 2 months ago

This intentional, but we can consider changing it.

Type name introspection is separate from Schema introspection in the spec, and the name SchemaIntrospectionQuery was picked to reflect that. In the general case, resolving __typename nested inside of a field may requires “actual” execution if that field has an interface or union type.

Specifically at the root of an operation however, because all root operation types must be object types (not interface or union), __typename could be correctly resolved based on only the schema. And since bare { __typename } is a semi-common “is this URL a running GraphQL server” query it may be worth bending the definition a bit and resolving it like schema introspection without involving “normal” execution machinery.

yanns commented 2 months ago

Thanks for the explanation, it makes perfect sense.

And I guess that Operation::is_introspection returns true for all kinds of introspection, schema and type name? I'm using this information to know if it's an introspection query, and in that case I'm using SchemaIntrospectionQuery . But this will not work for type name introspection. Do you think we should introduce more fine grained Operation::is_introspection?

SimonSapin commented 2 months ago

The concept of a is_introspection method that returns a boolean is wrong since you can query __schema and "normal" fields in the same operation. I’d like to remove it after Router fully moves to the Rust implementation of introspection. Its replacement is SchemaIntrospectionSplit::split