Apollo 中的缓存避免 GraphQL 解析多态关联

Cache in Apollo is avoiding GraphQL from resolving the polymorphic association

在 GraphQL(Apollo、Sequelize 和 SQLite)中,我使用字段来解析多态关联的模型类型。缓存的时候出现解析关联的问题

后端:

class AssignTModel extends Model {
    async getAction(options)  {     
        if (!this.actionType) return Promise.resolve(null);
            const mixinMethodName = `get${uppercaseFirst(this.actionType)}`;
            const action=await this[mixinMethodName](options);
            if (action) action.myResolve=this.actionType;
            return action;
        }
    }
    AssignTModel.init({
        id:{ type: Sequelize.INTEGER,
            primaryKey: true,
            autoIncrement: true     },
    . . .
        actionId:{ type: Sequelize.INTEGER},
        actionType:{ type: DataTypes.STRING },
    }, {sequelize,modelName: 'assignt'});
    . . .
    AssignTModel.belongsTo(ReminderModel, { foreignKey: 'actionId', constraints: false });
    AssignTModel.belongsTo(ServiceModel, { foreignKey: 'actionId', constraints: false });
    const AssignT = sequelize.models.assignt;
    . . .
const typeDefs = gql`
 union Action = Reminder | Service
    type AssignT{
        id:Int
  . . .

        action:Action
    }
. . .
    type Query {
      . . .
      action(id:Int):[Action],
    . . .

  const resolvers = {
. . .
    Action:{
        __resolveType(obj, context, info){
          if(obj && obj.myResolve && obj.myResolve === "reminder" ){
            return 'Reminder';
          }

          if(obj && obj.myResolve && obj.myResolve === "service" ){
            return 'Service';
          }
          return null;
        },
    },
. . .
    AssignT: {
        . . .
        action: async (assignt) => assignt.getAction(),
    },

前端:

在 React.JS 应用程序中,当我在查询上启用缓存时,我在解析多态关联时遇到问题:

FORM_QUERY = gql`query ($id:Int){
                  nodes:assignT(id:$id){
                    id
                    . . .
                    action {
                        ... on Reminder{
                            id
                            label
                          }
                        ... on Service{
                            id
                            label
                          }
                    }
                  }
                }`;

Not OK --> <Query query={FORM_QUERY} variables={{id:id}} fetchPolicy="cache-and-network">

OK --> <Query query={FORM_QUERY} variables={{id:id}} fetchPolicy="no-cache">

这个问题在 GraphQL Playground 上没有出现,这就是我怀疑 Cache 的原因。

如何在维护缓存的同时解决这个问题?

找到并解决。我发布答案是为了帮助遇到同样问题的人。

问题在于没有使用 IntrospectionFragmentMatcher。 事实上,我已经看到了这个警告,但我打算稍后解决它,并没有直接对我的问题进行link。

解决方法如下:

import { InMemoryCache, NormalizedCacheObject,IntrospectionFragmentMatcher } from 'apollo-cache-inmemory';
import {ApolloClient} from "apollo-boost";

const possibleTypes = {
  __schema: {
    types: [{
        kind: 'UNION',
        name: 'Action',
        possibleTypes: [
          { name: 'Service' },
          { name: 'Reminder' },
        ]
      },
    ]
  },
}

const fragmentMatcher = new IntrospectionFragmentMatcher({
    introspectionQueryResultData: possibleTypes
})
const cache = new InMemoryCache({
                    fragmentMatcher
                })
const uri= 'http://localhost:4000/';
const link = createHttpLink({ uri, fetch });
const client= new ApolloClient({
  cache,
  link
});