Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement 2-step introspection #5371

Merged
merged 6 commits into from
Nov 22, 2023
Merged

Implement 2-step introspection #5371

merged 6 commits into from
Nov 22, 2023

Conversation

BoD
Copy link
Contributor

@BoD BoD commented Nov 15, 2023

  1. execute a pre-introspection query used to get the server capabilities
  2. execute the base introspection query augmented according to the capabilities

The Gradle plugin is no longer used for that part, but still present and used by the Apollo Platform API related operations (registry, persisted queries, field insights, telemetry).

@BoD BoD requested a review from martinbonnin as a code owner November 15, 2023 18:58
Copy link

netlify bot commented Nov 15, 2023

Deploy Preview for apollo-android-docs canceled.

Name Link
🔨 Latest commit 69e7634
🔍 Latest deploy log https://app.netlify.com/sites/apollo-android-docs/deploys/655cb3cecbe75500082301ce

Comment on lines 117 to 118
// be robust to errors: [] keys
ignoreUnknownKeys = true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if a field errors (very unlikely to happen for an introspection query but 🤷 )? Should we output an error instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you get an error here, something is very wrong, so it would make sense to fail early I think.

Comment on lines 125 to 156
@Serializable
private class MIntrospection(
val data: MData
)

@Serializable
private class MData(
@Suppress("PropertyName")
val __schema: MSchema
)

@Serializable
private class MSchema(
val types: List<MType>,
)

@Serializable
private class MType(
val name: String,
val fields: List<MField>?,
)

@Serializable
private class MField(
val name: String,
val args: List<MInputValue>,
)

@Serializable
private class MInputValue(
val name: String,
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the meta introspection query, you could use Apollo and generate all of that automatically.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally, I was in a "don't use Apollo" mindset, but it makes sense to use it here actually - the code will be simpler 🎉

Comment on lines 1 to 3
# Base introspection query that will be augmented according to the server capabilities.
# The capabilities are retrieved by executing the meta-introspection query next to this file.
# The fields that can be added or modified are shown as comments.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a comment ~what version of the spec this corresponds to?

Comment on lines 4 to 14
__schema {
types {
name
fields {
name
args {
name
}
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Download only the required types?

query MetaIntrospectionQuery {
  __type(name: "__Schema") { ...typeDetails }
  __type(name: "__Type") { ...typeDetails }
  __type(name: "__Directive") { ...typeDetails }
  __type(name: "__Field") { ...typeDetails }
  __type(name: "__InputValue") { ...typeDetails }
}

It's not so much about the performance improvements but the fact that it conveys better what we're going to do with this data?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't realize it was allowed! Will update 👍

class SchemaDownloaderTests {
private lateinit var mockServer: MockServer
private lateinit var tempFile: File
private const val metaSchemaJune2018Response = """
Copy link
Contributor

@martinbonnin martinbonnin Nov 16, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: can those json files be moved to separate test fixture files so that we have less scrolling to do?

mockServer.enqueueString(statusCode = 400)
mockServer.enqueueString(statusCode = 400)
mockServer.enqueueString(schemaString1)
fun `schema is downloaded correctly when server supports Draft spec as of 2023-11-15`() = runTest(before = { setUp() }, after = { tearDown() }) {
Copy link
Contributor

@martinbonnin martinbonnin Nov 16, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@oneOf is not in the draft yet so it's more like server supports @oneOf nevermind, I read it wrong, the test is below 👍

Copy link
Contributor

@martinbonnin martinbonnin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! 👍

One last comment about bikeshedding the name 😃 . I have mixed feelings about "meta introspection query" as "meta" is quite the loaded term. The only suggestion I have in mind is "step1 introspection query" which isn't great either so I'm fine keeping this "meta" for now. Up to you.

@BoD
Copy link
Contributor Author

BoD commented Nov 17, 2023

One last comment about bikeshedding the name 😃 . I have mixed feelings about "meta introspection query" as "meta" is quite the loaded term. The only suggestion I have in mind is "step1 introspection query" which isn't great either so I'm fine keeping this "meta" for now. Up to you.

Agree meta wasn't great - I changed it to "pre-introspection query" 😁 LMKWYT

Comment on lines 32 to 55
/**
* `__Type.inputFields`, `includeDeprecated` argument, introduced in [Draft](https://spec.graphql.org/draft/)
*/
TypeInputFieldsIncludeDeprecated,

/**
* `__Directive.args`, `includeDeprecated` argument, introduced in [Draft](https://spec.graphql.org/draft/)
*/
DirectiveArgsIncludeDeprecated,

/**
* `__Field.args`, `includeDeprecated` argument, introduced in [Draft](https://spec.graphql.org/draft/)
*/
FieldArgsIncludeDeprecated,

/**
* `__InputValue.isDeprecated`, introduced in [Draft](https://spec.graphql.org/draft/)
*/
InputValueIsDeprecated,

/**
* `__InputValue.deprecationReason`, introduced in [Draft](https://spec.graphql.org/draft/)
*/
InputValueDeprecatedReason,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these are all the same? Does it make sense to include one but not the others?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More generally, the naming should be about "features" and not introspection names. Maybe SpecifiedBy, OneOf, DeprecatedInputValues, RepeatableDirectives, ...?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In 830615e I've renamed the enum to GraphQLFeature, and made it less granular.

Comment on lines 176 to 179
val metaSchemaMockResponse = MockResponse().setBody(preIntrospectionResponse)
val schemaMockResponse = MockResponse().setBody(schemaString1)
mockServer.enqueue(metaSchemaMockResponse)
mockServer.enqueue(schemaMockResponse)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

metaSchemaMockResponse -> preIntrospectionResponse

@BoD BoD force-pushed the 2-step-introspection branch from 85e52c8 to 69e7634 Compare November 21, 2023 13:42
@BoD BoD merged commit c40bcf8 into main Nov 22, 2023
7 checks passed
@BoD BoD deleted the 2-step-introspection branch November 22, 2023 08:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants