GraphQL突变为嵌套响应返回null
我有两种型号,公司和用户。从数据库的角度来看,一家公司有很多用户。在创建单个用户时,我希望通过返回与该用户关联的公司来利用graphQL的强大功能。但是,这仅在执行查询时有效。尝试变异时,对象会发生变异,但请求的关系数据始终返回null 在模型中,我们声明了一个一->多关系,并将公司模型模式包括在我们的用户模型模式中以访问数据 用户模型模式GraphQL突变为嵌套响应返回null,graphql,sequelize.js,apollo,Graphql,Sequelize.js,Apollo,我有两种型号,公司和用户。从数据库的角度来看,一家公司有很多用户。在创建单个用户时,我希望通过返回与该用户关联的公司来利用graphQL的强大功能。但是,这仅在执行查询时有效。尝试变异时,对象会发生变异,但请求的关系数据始终返回null 在模型中,我们声明了一个一->多关系,并将公司模型模式包括在我们的用户模型模式中以访问数据 用户模型模式 type User { clients: [Client!] company: Company <-------
type User {
clients: [Client!]
company: Company <------- Company Relation
companyId: UUID
confirmed: Boolean
defaultPortfolioSize: Int
email: String!
firstName: String!
lastLogin: String!
lastName: String!
id: UUID!
isActive: Boolean
isStaff: Boolean
isSuperuser: Boolean
password: String
phoneNumber: String
priceNotification: Boolean
priceThreshold: Float
sentimentNotification: Boolean
sentimentThreshold: Float
token: String
clientCount: Int
notificationCount: Int
portfolioCount: Int
stockAverageCount: Float
totalValue: Float
stockList: [PortfolioStock!]
}
数据加载器是魔法发生的地方。我们调用upsertUser来创建、更新和删除任何对象。在这里,我们成功地创建了一个用户,并可以在db中验证创建过程
用户数据加载器
upsertUser: async (user, params) => {
...
/* Register */
if (!params.companyId) {
throw new UserInputError("Missing 'companyId' parameter");
}
if (!params.password) {
throw new UserInputError("Missing 'password' parameter");
}
let newUser = new User({
billingAddressId: 0,
dateJoined: new Date(),
defaultPortfolioSize: 45,
isActive: true,
isStaff: false,
isSuperuser: false,
lastLogin: new Date(),
phoneNumber: '',
priceNotification: false,
priceThreshold: 0,
sentimentNotification: false,
sentimentThreshold: 0,
subscriptionStatus: false,
...params,
});
newUser = await newUser.save();
newUser.token = getJWT(newUser.email, newUser.id);
EmailManager(
EmailTemplate.CONFIRM_ACCOUNT,
`${config.emailBaseUrl}authentication/account-confirmation/?key=${
newUser.token
}`,
newUser.email
);
return newUser;
},
// Including the users query dataloader for reference
users: async params => {
return await User.findAll(get({ ...defaultParams(), ...params }));
},
下面是一个示例,我们创建了一个用户对象,并使用嵌套的公司关系请求响应
示例突变
mutation {
user(
companyId: "16a94e71-d023-4332-8263-3feacf1ad4dc",
firstName: "Test"
lastName: "User"
email: "test@gmail.com"
password: "PleaseWork"
) {
id
company {
id
name
}
email
firstName
lastName
}
}
但是,当请求将关系包括在响应对象中时,api返回null而不是对象
示例响应
ACTUAL:
{
"data": {
"user": {
"id": "16a94e71-d023-4332-8263-3feacf1ad4dc",
"company": null,
"email": "test@gmail.com",
"firstName": "Test",
"lastName": "User"
}
}
}
EXPECTED:
{
"data": {
"user": {
"id": "16a94e71-d023-4332-8263-3feacf1ad4dc",
"company": {
"id": "16a94e71-d023-4332-8263-3feacf1ad4dc",
"name": "Test Company",
},
"email": "test@gmail.com",
"firstName": "Test",
"lastName": "User"
}
}
}
我想我有点困惑,为什么graphQL不能在突变期间对我的嵌套对象进行图形化,但可以通过查询进行图形化。问题在于Sequelize。由于表的突变不与其关联共享,因此突变对象不像典型查询那样包含所述关联。因此,从变异对象请求的任何关联都将返回null,因为该对象不直接存在于模型中 也就是说,有几种方法可以补充这个问题
特别是,如果您想通过此模型直接改变这些关联。如果是这样的话,我建议查看Sequelize。问题在于Sequelize。由于表的突变不与其关联共享,因此突变对象不像典型查询那样包含所述关联。因此,从变异对象请求的任何关联都将返回null,因为该对象不直接存在于模型中 也就是说,有几种方法可以补充这个问题
特别是,如果您想通过此模型直接改变这些关联。如果是这样的话,我建议查看Sequelize的。Daniel Reardan可能会通过他的解释链接回答这个问题:。我了解到GraphQL消息非常普遍,问题可能是许多问题之一。最好从Daniel的解决方案开始。@Preston感谢您的回复,我会检查它。如果您说您在查询时成功检索到了公司信息。如何检索给定用户的公司数据?如果您使用标准的DB连接进行此操作,则您的
新用户
数据可能不完整,并且不包含公司
信息。理想情况下,您希望在用户
类型上为公司
字段指定一个特定的解析器,并以这种方式实现您的关联;这将保证无论何时您返回类型用户
(当然,如果查询了公司
字段),解析程序都将始终运行。Daniel Reardan可能会通过其解释的链接回答此问题:。我了解到GraphQL消息非常普遍,问题可能是许多问题之一。最好从Daniel的解决方案开始。@Preston感谢您的回复,我会检查它。如果您说您在查询时成功检索到了公司信息。如何检索给定用户的公司数据?如果您使用标准的DB连接进行此操作,则您的新用户
数据可能不完整,并且不包含公司
信息。理想情况下,您希望在用户
类型上为公司
字段指定一个特定的解析器,并以这种方式实现您的关联;这将保证无论何时返回类型用户
(当然,如果查询了公司
字段),解析程序都将始终运行。
mutation {
user(
companyId: "16a94e71-d023-4332-8263-3feacf1ad4dc",
firstName: "Test"
lastName: "User"
email: "test@gmail.com"
password: "PleaseWork"
) {
id
company {
id
name
}
email
firstName
lastName
}
}
ACTUAL:
{
"data": {
"user": {
"id": "16a94e71-d023-4332-8263-3feacf1ad4dc",
"company": null,
"email": "test@gmail.com",
"firstName": "Test",
"lastName": "User"
}
}
}
EXPECTED:
{
"data": {
"user": {
"id": "16a94e71-d023-4332-8263-3feacf1ad4dc",
"company": {
"id": "16a94e71-d023-4332-8263-3feacf1ad4dc",
"name": "Test Company",
},
"email": "test@gmail.com",
"firstName": "Test",
"lastName": "User"
}
}
}
let client = new Client(
{
...params
},
{ include: [ClientGroup] }
);
return client.save()
await Client.update(params, {
// @ts-ignore: Unknown property 'plain'
plain: true,
returning: true,
where: { id: params.id },
});
return await Client.findOne({
include: [ClientGroup],
where: { id: params.id },
});