graphql - Apollo gateway s TypeScriptom neprijíma používateľské ID v kontexte


Snažím sa implementovať nový Apollo gateway pomocou TypeScriptu. Ale stále narazím na jeden problém s TypeScriptom, ktorý sa mi jednoducho nedarí vyriešiť. Chybová správa je "Vlastnosť 'userId' neexistuje na type 'TContext'.ts(2339)". Upozorňujem, že sa snažím implementovať to na AWS Lambda.

Pokiaľ vidím pri pohľade na zdrojový kód balíka, TContext=Record je objekt, ale zdá sa, že sa nedá vyriešiť.

import { ApolloServer } from 'apollo-server-lambda';
import { ApolloGateway, RemoteGraphQLDataSource } from '@apollo/gateway';


const gateway = new ApolloGateway({
  serviceList: [
    { name: 'users', url: 'xx' },
    { name: 'precedents', url: 'xx' }
    // other services
  ],
  buildService({ url }) {
    return new RemoteGraphQLDataSource({
      url,
      willSendRequest({ request, context }) {
        // pass the user's id from the context to underlying services
        // as a header called `user-id`
        request && request.http && request.http.headers.set('user-id', context.userId);
      }
    });
  }
});

const server = new ApolloServer({
  gateway,
  subscriptions: false,
  context: ({ event, context }) => {
    // get the user token from the headers
    const token = event.headers.authorization || '';

    // try to retrieve a user with the token
    const userId = token;

    // add the user to the context
    return {
      headers: event.headers,
      functionName: context.functionName,
      event,
      context,
      userId
    };
  }
});

exports.handler = server.createHandler({
  cors: {
    origin: true,
    credentials: true,
    methods: ['POST', 'GET'],
    allowedHeaders: ['Content-Type', 'Origin', 'Accept', 'authorization']
  }
});

Upraviť Aktualizácia podľa nižšie uvedeného sa zdá, že vedie k rovnakému problému.

interface MyContext{
    userId: string;
}

const gateway = new ApolloGateway({
  serviceList: [
    { name: 'users', url: 'xx' },
    { name: 'precedents', url: 'xx' }
    // other services
  ],
  buildService({ url }) {
    return new RemoteGraphQLDataSource({
      url,
      willSendRequest<MyContext>({ request, context } : {request: GraphQLRequest, context: MyContext}) {
        // pass the user's id from the context to underlying services
        // as a header called `user-id`
        request && request.http && request.http.headers.set('user-id', context.userID);
      }
    });
  }
});

Odpoveď č. 1

Najprv vytvorte rozhranie, ktoré bude opisovať váš GraphQL kontext

interface MyContext{
    userId: string;
}

Potom pridajte typový parameter MyContext do metódy willSendRequest takto

...
willSendRequest<MyContext>({request, context}) {
...

Teraz kompilátor vie, že kontext je typu MyContext.