How do I send a graphQL query that contains an extended query?

Viewed 268

I have an graphene.ObjectType model on one of my services which extends a definition in another service

@extend(fields="id")
class ExtendedProtectedObject(graphene.ObjectType):
    id = external(graphene.ID(required=True))
    additional_color = graphene.String()

    class Meta:
        interfaces = (relay.Node,)

    def resolve_additional_color(self, info):
        return "blue"

    @staticmethod
    def _ExtendedProtectedObject__resolve_reference(root, info):
        # root is an instance of self class with id set to the query id value
        return root

We run Apollo Federation to combine all of our graphql schemas in onle location and to route queries/mutations etc. What query can I add as a unit test in my service which mirrors what Apollo does when I request on my additionalColor field? For example this query:

query getExtendedProtectedObject($id: ID!) {
    extendedProtectedObject(id: $id) {
        additionalColor
    }
}

What query does federation forward on to my service? I want to use that query in one of my unit tests in my service because it calls the ExtendedProtectedObject method _ExtendedProtectedObject__resolve_reference before hitting any field resolvers.

1 Answers

One can do this with this query:

query ($representations:[_Any!]!) {
    _entities(representations:$representations) {
        ...on ExtendedProtectedObject {
            additionalColor
        }
    }
}

and use these query variables:

variables=dict(
    representations=[{"__typename": "ExtendedProtectedObject", "id": to_global_id("ExtendedProtectedObject", 1)}],
)

Per the Apollo docs

Validation Errors Returned Client Side For Above Query

Just a heads up, when I tried to submit that query from a client, it fails an Apollo server validation step. Under the hood federation will send this query to your service when a normal query is sent in which requires resolving fields in an extended ObjectType.

Security Implication If Validation Off + Query Can Hit Service

So if you have validation turned off one could use this query to target a response to only one of your services. If validation is turned off, for a type like Me this could be a security vulnerability if this query can be successfully executed by a client. This is because it would allow a query to set an external global id and hit a service directly, circumventing the source of the Me get_node and Me.resolve_id, and instead only hit Me._Me__resolve_reference and any service specific resolvers. This assumes that id is the only key field.

Related