graphql将动态数据传递给突变

时间:2019-10-10 03:31:50

标签: javascript graphql apollo-server

以前没有使用过graphqlmongodb。为更新突变传递对象的正确方法是什么?

由于我看到传递多个动态出现的参数的唯一另一种方法是使用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
            };
        }
}

有什么建议可以更好地解决这个问题?

谢谢!

1 个答案:

答案 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