Федерация Аполлона с сервером шлюза как сервисом - PullRequest
1 голос
/ 07 июня 2019

Краткое описание проблемы описано в выпуске Github:

https://github.com/apollographql/apollo-server/issues/2794


Короче говоря, есть ли способ реализовать федерацию Apollo, чтобы сам шлюз имел свою собственную схему?

Объединение сервера Apollo, где сам шлюз имеет схему

@apollo/gateway@0.6.5 @apollo/federation@0.6.2

Ожидаемое поведение

Когда я создаю экземпляр своего сервера Apollo Gateway, я ожидаю, что смогу объединить схемы из федеративных служб, а также схему из самого шлюза.

Фактическое поведение

Серверу шлюза не удается смонтировать маршрут /graphql, поскольку он ожидает, что все службы будут запущены в данный момент, прежде чем он это сделает.

Во время выполнения на консоль выводится следующая ошибка:

POST /graphql 404 11.251 ms - 147
Encountered error when loading gateway-app at http://localhost:8000/graphql: invalid json response body at http://localhost:8000/graphql reason: Unexpected token < in JSON at position 0
[DEBUG] Fri Jun 07 2019 12:11:07 GMT-0400 (Eastern Daylight Time) apollo-gateway: Configuration loaded for Gateway
[DEBUG] Fri Jun 07 2019 12:11:07 GMT-0400 (Eastern Daylight Time) apollo-gateway: Composing schema from service list:
  remove-svc
TypeError: schema.toConfig is not a function
    at Object.composeServices (/gateway-app/node_modules/@apollo/federation/dist/composition/compose.js:191:67)
    at Object.composeAndValidate (/gateway-app/node_modules/@apollo/federation/dist/composition/composeAndValidate.js:13:41)
    at ApolloGateway.createSchema (/gateway-app/node_modules/@apollo/gateway/dist/index.js:90:47)
    at ApolloGateway.<anonymous> (/gateway-app/node_modules/@apollo/gateway/dist/index.js:81:22)
    at Generator.next (<anonymous>)
    at fulfilled (/gateway-app/node_modules/@apollo/gateway/dist/index.js:4:58)
    at process._tickCallback (internal/process/next_tick.js:68:7)

Исходный код

const url = new URL(`redis://${REDIS_URL}:${REDIS_PORT}/${REDIS_DATABASE}`).toString()

const cache = new RedisCache({ url })

const context = ({ req }) => {
  if (!(req.user || req.headers.authorization === ROUTE_AUTH)) {
    throw new AuthenticationError('Not authenticated')
  }
  return { user: req.user, req: req }
}

try {
  const loadGateway = async () => {
    try {
      const { schema, executor } = await gateway.load()
      return { schema, executor }
    } catch (err) {
      console.error(err)
      return null
    }
  }

  const gateway = new ApolloGateway({
    debug: process.env.ENV !== 'prod',
    serviceList: [
      { name: 'gateway', url: `${GATEWAY_HOSTNAME}/graphql` },
      { name: 'remote-svc', url: `${REMOTE_SERVICE_HOSTNAME}/graphql` },
    ],
  })

  const { schema, executor } = loadGateway()
  const server = new ApolloServer({
    schema,
    executor,
    cache,
    dataSources,
    engine: { apiKey: ENGINE_API_KEY },
    tracing: true,
    context,
  })
  server.applyMiddleware({ app })
} catch (err) {
  console.error(err)
}

1 Ответ

1 голос
/ 11 июня 2019

На основании исходных ошибок, обнаруженных моей проблемой, есть две ошибки.

  1. Сервер Apollo Gateway не может и не должен быть федеративной службой со своей собственной схемой (см. Github Issue # 2792 ).

От Аполлона:

Я подойду к выводу, основанному на названии вашей службы: вы пытаетесь запустить шлюз на порту 8000 и одновременно рассматривать его как федеративную службу? Если так, это не сработает; шлюз должен разрешить все схемы, прежде чем он сможет составить окончательную схему.

  1. Зависимость ядра GraphQL должна быть не ниже версии 14.2.0 (см. Github Issue # 2825 ).

Из журнала изменений GraphQL JS:

toConfig предназначен для помощи в преобразовании схемы, сводя к минимуму объем кода, который вам нужно написать и поддерживать, например, воссоздать тип из graphql-tools.

Когда я работал над graphql-voyager, я создал свой собственный промежуточный формат просто для преобразования схемы.

Более того, toConfig предотвратит ошибки, возникающие при добавлении нового поля. Например, lexicographicSortSchema не учитывает вновь добавленные поля acceptValid и allowLegacyNames.

После миграции схемы со шлюза на его собственную федеративную службу и обновления моей основной зависимости GraphQL до соответствующей версии я смог успешно реализовать шаблон шлюза / федерации.

...