Apollo 中的缓存正在避免 GraphQL 解决多态关联
Posted
技术标签:
【中文标题】Apollo 中的缓存正在避免 GraphQL 解决多态关联【英文标题】:Cache in Apollo is avoiding GraphQL from resolving the polymorphic association 【发布时间】:2020-11-14 01:48:26 【问题描述】:在 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 上没有出现这个问题,这就是我怀疑缓存的原因。
如何在维护缓存的同时解决这个问题?
【问题讨论】:
我想我也有同样的问题。您能否提供有关它引发的错误的更多详细信息? @Thomas 它在操作为提醒时有效,并且在操作为服务时根本不加载数据(我得到空数据),并针对在提醒中定义但不在服务中定义的字段发出警告。跨度> 【参考方案1】:找到并解决。我正在发布答案,以便它可以帮助面临同样问题的人。
问题在于没有使用 IntrospectionFragmentMatcher。 事实上,我已经看到了这个警告,但我打算稍后解决它,并没有直接链接到我的问题。
解决方法如下:
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
);
【讨论】:
以上是关于Apollo 中的缓存正在避免 GraphQL 解决多态关联的主要内容,如果未能解决你的问题,请参考以下文章
GraphQL + Apollo - 如何强制进行查询,似乎正在缓存一些东西
(GraphQL) - 为啥 Apollo 先检查缓存,然后再做其他事情?
更新 apollo 缓存而不调用 graphql 服务器(apollo v3.3)
使用 Apollo 和 GraphQL 缓存而不是 Vuex?