以前没有使用过graphql
或mongodb
。为更新突变传递对象的正确方法是什么?
由于我看到传递多个动态出现的参数的唯一另一种方法是使用input
类型,这对我来说似乎有点无效(就其在代码中的外观而言,尤其是对于较大的对象而言) ),我只是自己传递可能的值。但是,在这种情况下,我需要动态构造updateObject
,对于较大的模型,它又会变得混乱。
例如,现在我做了:
Mutation: {
updateHub: async (_, { id, url, ports, enabled }) => {
const query = {'_id': id};
const updateFields = {
...(url? {url: url} : null),
...(ports? {ports: ports} : null),
...(enabled? {enabled: enabled} : null)
};
const result = await HubStore.findByIdAndUpdate(query, updateFields);
return {
success: !result ? false : true,
message: 'updated',
hub: result
};
}
}
有什么建议可以更好地解决这个问题?
谢谢!
答案 0 :(得分:1)
似乎您的代码可以通过使用ES6扩展语法而受益-它将使您可以处理args
对象中的任意数量的属性,而无需使用串行第三级语句。
Mutation: {
updateHub: async (_, { id, ...restArgs } ) => {
const query = {'_id': id};
const updateFields = { ...restArgs };
const result = await HubStore.findByIdAndUpdate(query, updateFields);
return {
success: !result ? false : true,
message: 'updated',
hub: result
};
}
}
如果出于某种原因需要在对象中将未定义的属性显式设置为null
,则可以使用lodash库中的一些配置obj和方法,例如defaults
,如下所示:< / p>
import { defaults } from 'lodash';
const nullFill = { url: null, ports: null, enabled: null }; // include any other properties that may be needed
Mutation: {
updateHub: async (_, { id, ...restArgs } ) => {
const query = {'_id': id};
const updateFields = defaults(restArgs, nullFill);
const result = await HubStore.findByIdAndUpdate(query, updateFields);
return {
success: !result ? false : true,
message: 'updated',
hub: result
};
}
}
另外,FWIW,我会考虑将可能会更新的动态参数放在其自己的输入类型上,例如graphql docs中建议的HubInput
。下面,我显示了这如何与您的突变一起使用。请注意,由于HubInput上的任何内容均未标记为必需(!
),因此您可以传递动态的属性集合以进行更新。还要注意,如果采用这种方法,则首先需要在您的突变中适当地破坏args
对象,例如{ id, input }
。
input HubInput {
url: String
ports: // whatever this type is, like [String]
enabled: Boolean
// ...Anything else that might need updating
}
type UpdateHubPayload {
success: Boolean
message: String
hub: Hub // assumes you have defined a type Hub
}
updateHub(id: Int, input: HubInput!): UpdateHubPayload