首页 > 解决方案 > 无缝迁移到 Postgraphile(多个 ApolloClient 实例)

问题描述

Postgraphile 似乎非常方便的工具,但我已经在客户端和服务器端有数十个查询和突变。

有什么方法可以将 Postgraphile 一块一块地集成,让我的旧 GraphQL 模式由手工描述?

所以,现在我有以下初始化代码:

function createApolloLink(){
  return createHttpLink({
    uri: '/graphql',
    credentials: 'same-origin'
  });
}

function create(){
  return new ApolloClient({
    link: createApolloLink(),
    ssrMode: !process.browser, // eslint-disable-line
    cache: new InMemoryCache(),
    connectToDevTools: process.browser
  });
}

如何利用一个标准化存储(客户端)并连接到由 Postgraphile 驱动的第二个 API 点,例如/graphql2

标签: graphqlreact-apolloapollo-clientpostgraphql

解决方案


通常,您的 GraphQL 客户端不必考虑这一点 - 它应该在服务器端处理。

您可以使用多种技术在服务器端解决此问题:

模式拼接

模式拼接是解决您的问题的直接方法 - 获取旧模式并将其与您的 PostGraphile 模式合并;这样,当客户与之通信时,/graphql他们就可以访问这两种模式。然后,您可以将旧架构中的所有内容标记为已弃用并逐渐淘汰使用。但是,如果可以的话,我建议您使用 PostGraphile 插件...

PostGraphile 插件

PostGraphile 是围绕插件系统构建的,您可以使用类似的东西makeExtendSchemaPlugin将旧的 GraphQL 模式混合到 PostGraphile 模式中。这记录在这里:https ://www.graphile.org/postgraphile/make-extend-schema-plugin/但是如果您的旧类型/解析器是通过类似graphql-tools这样的方式实现的,那么这可能是最简单的入门方法:

const { makeExtendSchemaPlugin, gql } = require('graphile-utils');

const typeDefs = gql`\
type OldType1 {
  field1: Int!
  field2: String
}
extend type Query {
  oldField1: OldType1
  oldField2: OldType2
}
`;

const resolvers = {
  Query: {
    oldField1(/*...*/) {
      /* old logic here */
    },
    //...
  },
};

const AddOldSchemaPlugin = makeExtendSchemaPlugin(
  build => ({
    typeDefs,
    resolvers,
  })
);

module.exports = AddOldSchemaPlugin;

这也将带来最佳性能,因为不应增加延迟,并且您可以再次将遗留字段/突变标记为已弃用。

模式委托

使用这种方法,您可以编写自己的新 GraphQL 模式,然后将其“委托”给其他 GraphQL 模式(旧模式和 PostGraphile 生成的模式)。这会增加一点延迟,但可以让你更好地控制 GraphQL 模式的最终形状,尽管这种能力带来了巨大的责任——如果你犯了一个错字,那么你将不得不长时间保持这个错字!就个人而言,我更喜欢 PostGraphile 使用的生成模式方法。


但是,为了回答您提出的问题,Apollo Link 具有“上下文”功能,允许您更改查询的执行方式。通常这用于添加标头,但您也可以使用它来覆盖 URI 以确定查询可以去哪里。我自己从来没有这样做过,但是如果有一个 Apollo Link 可以使用,它会根据客户端指令甚至字段名称自动切换,我不会感到惊讶。

https://github.com/apollographql/apollo-link/tree/master/packages/apollo-link-http#context


推荐阅读