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
});
在 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
});