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

Directives do not get reported through _service.sdl introspection query ---> subgraph cannot be federated #736

Open
magicmark opened this issue Dec 4, 2021 · 3 comments
Labels

Comments

@magicmark
Copy link

magicmark commented Dec 4, 2021

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:

Screen Shot 2021-12-03 at 11 10 13 PM

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

Screen Shot 2021-12-03 at 11 09 37 PM

^ 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!

@magicmark magicmark changed the title Directives do not get Directives do not get reported through _service.sdl introspection query ---> subgraph cannot be federated Dec 4, 2021
@magicmark
Copy link
Author

magicmark commented Dec 4, 2021

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)

@lschmierer
Copy link

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)

@lschmierer
Copy link

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.

@rafalp rafalp added the roadmap Feature that we want to have included label Jul 21, 2023
@TMuszczekk TMuszczekk added to do and removed roadmap Feature that we want to have included labels Mar 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants