question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

applyMiddleware corrupts schema with Apollo federation `stub types`

See original GitHub issue

We are using Apollo federation https://www.apollographql.com/docs/federation/federation-spec/ where gateway combines two graphql schemas into one unified schema.

We have vanilla ordinary setup for it

We have type user in service A

@ObjectType()
@Directive('@key(fields: "id")')
export class User {
  @Field(() => Int)
  public id: number;

  @Field()
  public firstname: string;

  @Field()
  public lastname: string;
}

And we have type stub type User in service B

@ObjectType()
@Directive('@extends')
@Directive('@key(fields: "id")')
export class User {
  @Directive('@external')
  @Field(() => Int)
  id: number;
}

And we have type Equipment in service B that refers to the user

import { User } from './User';

@ObjectType()
export class Equipment {
  @Field(() => ID)
  id: number;

  // external type
  @Type(() => User)
  @Field({ nullable: true })
  owner?: User;

  @Field(() => Date)
  createdAt: Date;
}

By applying this trivial middleware in the service A

const doNothing: IMiddlewareResolver = async (
  resolve,
  root,
  args,
  context,
  info
) => {
  return resolve(root, args, context, info);
};

GraphQL will be unable to resolve external fields for the User. i.e. This will work

query {
  equipments {
    id
    name
    owner {
      id
    }
  }
}

But this will start to fail

query {
  equipments {
    id
    name
    owner {
      id
      lastname
    }
  }
}

with error message Cannot return null for non-nullable field User.lastname.

I was unable to pinpoint what is going on, but I see that the schemas ar slightly different after running applyMiddleware(doNothing)

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:5
  • Comments:6

github_iconTop GitHub Comments

4reactions
durgesh-mfscommented, Jun 24, 2021

@jekabs-karklins have you found solution?

I have similar schema design to yours and getting similar error. I was using v4.0.2 everything was working expected but recently I have update to latest version(v6.0.10) and then started getting this issue. I have also tested v4.0.3 seems like working everything as expected but not working in 5.0.0 and above

2reactions
plfxcommented, Feb 8, 2022

I found a solution. You need to check whether the resolver is one of the type fields for the Apollo Federation spec, and simply make your middleware a no-op when it matches.

(TypeScript)



function isFederationIntrospectionQuery({
  prev,
  key,
  typename,
}: GraphQLResolveInfo['path']): boolean {
  if (prev) {
    return isFederationIntrospectionQuery(prev);
  } else {
    return (key == '_entities' || key == '_service') && typename == 'Query';
  }
}

// ...

applyMiddleware(
      schema,
      async (resolve, root, args, context, info) => {
        if (isFederationIntrospectionQuery(info.path)) {
          // no-op
          return resolve(root, args, context, info);
        }
        
        // etc...

Could this logic get rolled into graphql-middleware, or some utility or option be added to make this easier?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Value types in Apollo Federation
This article describes how to share value types and their fields in federated graph, enabling multiple subgraphs to define and resolve them. Sharing...
Read more >
Issues · maticzav/graphql-middleware
Type generator exists in middleware but is missing in Schema. #433 opened on Aug 18, ... applyMiddleware corrupts schema with Apollo federation stub...
Read more >
Top 5 @apollo/federation Code Examples
price > 1000) return 0; // estimate is based on weight return object.weight * 0.5; } } }; const server = new ApolloServer({...
Read more >
Getting Started with Apollo Federation and Gateway
Having used schema stitching to join GraphQL APIs together in the past, the declarative, no-fuss approach offered by Apollo Federation was a ...
Read more >
Maticzav Graphql-Middleware Statistics & Issues - Codesti
applyMiddleware corrupts schema with Apollo federation `stub types`, open, 6, 2021-05-26, 2022-12-12, -. docs: Clarification Middleware vs Plugins, open ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found