Schema not completely fetched from introspection query
Jonas1312 opened this issue · 12 comments
Hi,
First, thanks a lot for gql!
Describe the bug
When fetching the schema from the backend, some @deprecated
fields are missing.
To Reproduce
gql-cli https://preproduction.cloud.kili-technology.com/api/label/v2/graphql --print-schema > schema_preprod.graphql
The fetched schema shows this:
input OrganizationData {
license: String
name: String
}
while the real schema looks like this:
input OrganizationData {
address: String @deprecated(reason: "This information is not relevant")
city: String @deprecated(reason: "This information is not relevant")
country: String @deprecated(reason: "This information is not relevant")
license: String
name: String
zipCode: String @deprecated(reason: "This information is not relevant")
}
Expected behavior
The schema fetching method(s) should not skip deprecated fields.
System info (please complete the following information):
- OS: macos
- Python version: 3.7
- gql version: v3.5.0b3
- graphql-core version: 3.3.0a2
Thanks
I checked with the GitHub GraphQL API:
gql-cli https://api.github.com/graphql --header "Authorization: Bearer MYTOKEN" --print-schema > github_schema.txt
and deprecated fields are present in the downloaded schema.
Example:
"""Represents an 'assigned' event on any assignable object."""
type AssignedEvent implements Node {
"""Identifies the actor who performed the event."""
actor: Actor
"""Identifies the assignable associated with the event."""
assignable: Assignable!
"""Identifies the user or mannequin that was assigned."""
assignee: Assignee
"""Identifies the date and time when the object was created."""
createdAt: DateTime!
id: ID!
"""Identifies the user who was assigned."""
user: User @deprecated(reason: "Assignees can now be mannequins. Use the `assignee` field instead. Removal on 2020-01-01 UTC.")
}
So either your backend decided to remove those deprecated fields, or for some reason they don't send them in response of an instrospection query.
Well those deprecated fields are still showing on apollo: https://studio.apollographql.com/sandbox/schema/reference/inputs/OrganizationData?query=OrganizationData (enter this endpoint: https://preproduction.cloud.kili-technology.com/api/label/v2/graphql)
They are still in the backend.
So I don't understand where they are being removed
I'll try to investigate
You can use --debug
to see the answer of the server. I attached the answer received below. You can see the 106th type only contains license
and name
Alright, I just found out that in our introspection query, we use includeDeprecated:true
for the fields
and enumValues
but not for the inputFields
.
̶T̶h̶i̶s̶ ̶c̶o̶u̶l̶d̶ ̶b̶e̶ ̶a̶ ̶b̶u̶g̶ ̶i̶n̶ ̶g̶r̶a̶p̶h̶q̶l̶-̶c̶o̶r̶e̶.̶
Investigating further...
graphql-core added support for deprecated input values on 2021-08-06 in this commit but by default it was not enabled.
The prototype for get_introspection_query
is:
def get_introspection_query(
descriptions: bool = True,
specified_by_url: bool = False,
directive_is_repeatable: bool = False,
schema_description: bool = False,
input_value_deprecation: bool = False,
) -> str:
"""Get a query for introspection.
In gql, to get the introspection query, we're just calling get_introspection_query()
without arguments so we don't get deprecated input values.
Ah I see, thanks for investigating!
As a workaround, you can get the complete schema by running:
import asyncio
from gql import Client, gql
from gql.transport.aiohttp import AIOHTTPTransport
from graphql import get_introspection_query, print_schema, parse, build_client_schema
async def main() -> int:
transport = AIOHTTPTransport(
url="https://preproduction.cloud.kili-technology.com/api/label/v2/graphql"
)
# Connect to the backend and provide a session
async with Client(transport=transport) as session:
execution_result = await session.execute(
parse(get_introspection_query(input_value_deprecation=True))
)
schema = build_client_schema(execution_result)
schema_str = print_schema(schema)
print(schema_str)
asyncio.run(main())
ok thanks
Do you plan to release a patch for that by any chance?
Do, you plan to release a patch for that by any chance?
Yes, thanks for your report!
@Cito, what arguments should we use by default in gql to make the introspection query? I'll add input_value_deprecation=True
, but does it make sense to use other arguments in get_introspection_query
? What about these arguments:
- specified_by_url
- directive_is_repeatable
- schema_description
Should I enable all of them?
Hi @leszekhanusz - in GraphQL.js, all of these parameters are false by default, and GraphQL-core always mimics the behavior there. I guess this is because not all servers may support these introspections (I think input value deprecation is only possible since the latest draft of the GraphQL spec). But of course you're free to use more reasonable defaults and/or make it configurable on your side, too. It may be also useful to be able to not fetch descriptions if you don't need them (which is the only parameter that is set to true by default).
You're right, I made some tests and for example the GitHub GraphQL API does not support any of those three options:
specified_by_url
directive_is_repeatable
schema_description
The kili-technology.com backend above support directive_is_repeatable
and schema_description
but we have this prob with specified_by_url
:
Cannot query field "specifiedByURL" on type "__Type". Did you mean "specifiedByUrl"?
So it is clear that I cannot modify the default without a potential breaking change and users will need to specify those options themselves.
So In the PR #402 I made this configurable in the Client
init and in the gql-cli script.
To download the schema with deprecated input fields, you now have to run:
gql-cli https://preproduction.cloud.kili-technology.com/api/label/v2/graphql --print-schema --schema-download input_value_deprecation:true
Hi,
I'm going to try your PR
edit: fixed the issue, thanks a lot