ariadne
ariadne copied to clipboard
Directives do not get reported through _service.sdl introspection query ---> subgraph cannot be federated
Apollo federation uses the following introspection query when glueing together subgraphs: https://github.com/apollographql/rover/blob/83d99ad2c707a5da4e3d48593af7b22a51d6d07d/crates/rover-client/src/operations/subgraph/introspect/introspect_query.graphql#L1-L6
query SubgraphIntrospectQuery {
# eslint-disable-next-line
_service {
sdl
}
}
In our subgraph, we define a schema only, non-executable @lint
directive. If I do an introspection for directives directly, it shows up, with all the other directives:

But if I run the introspection query apollo rover is using (@apollo/[email protected]
):

^ That's just some random test schema, but cruicially - no directives in the output.
This ultimately leads to the following:
error[E029]: Encountered 1 build error while trying to build a supergraph.
Caused by:
Encountered 1 build error while trying to build the supergraph.
UNKNOWN: [@lint] -> Custom directives must be implemented in every service. The following services do not implement the @lint directive: i18n_strings.
I'll keep poking around, it's possible i'm missing a trick here somewhere, or need to upgrade things, but writing this down as a starting point. Thanks!
super gross, i'm sure there's a better answer out there, but in case not...here's what i came up with
def fix_directives_in_sdl_introspection(handler, registry):
def fix_sdl(request):
response = handler(request)
if (
request.content_type != "application/json"
or request.json_body["operationName"] != "SubgraphIntrospectQuery"
):
# skip if it's not an _service.sdl introspection query.
return response
assert("_service" in request.json_body["query"], "Expected Query._service.sdl as the introspection query for SubgraphIntrospectQuery")
assert("sdl" in request.json_body["query"], "Expected Query._service.sdl as the introspection query for SubgraphIntrospectQuery")
json_body = response.json_body
json_body["data"]["_service"]["sdl"] += """
directive @lint(disable: [String!] = [], enable: [String!] = []) on QUERY | MUTATION | SUBSCRIPTION | FIELD | FRAGMENT_DEFINITION | FRAGMENT_SPREAD | INLINE_FRAGMENT | SCHEMA | SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
"""
response.json_body = json_body
return response
return fix_sdl
(if i haven't just missed a config setting, then the "real" answer would be to PR and get ariadne to return this via the sdl introspection field normally)
I am running into this issue as well.
@magicmark I am quite new to Ariadne and ASGI in general, where do I apply the fix_directives_in_sdl_introspection
function you provided?
This is how I am setting up my serivice:
...
schema = make_federated_schema(type_defs, query, directives={"isNotAuthenticated": IsNotAuthenticatedDirective, "hasRole": HasRoleDirective})
app = GraphQL(schema)
As far as I can tell, while Apollo Gateway is fine with stripping TypeSystemDirectiveLocation directive definitions, ExecutableDirectiveLocation directive definitions are expected to be returned in _service { sdl }
.
A solution would be to change https://github.com/mirumee/ariadne/blob/master/ariadne/contrib/federation/utils.py#L60 to only purge TypeSystemDirectives and keep ExecutableDirectives or even delete the line completely.
In my experience, the current implementation of Apollo Gateway is not bothered by _service { sdl }
containing TypeSystemDirectives.