【问题标题】:graphql passing dynamic data to mutationgraphql将动态数据传递给突变
【发布时间】:2020-02-07 10:26:54
【问题描述】:

之前没有使用过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
            };
        }
}

有什么更好的处理方法的建议吗?

谢谢!

【问题讨论】:

    标签: javascript graphql apollo-server


    【解决方案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,您可以使用一些配置 obj 和方法,例如来自 lodash 库的defaults,如下所示:

    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,我会考虑将可能被更新的动态参数放在它自己的输入类型上,例如HubInput 在这种情况下,正如graphql docs 中所建议的那样。下面我展示了这如何与您的突变一起使用。请注意,由于 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
    

    【讨论】:

    • 感谢您如此详细的回复!我想我错过了可以以这种方式使用扩展运算符,酷!您能否详细说明动态参数的单独类型的可能实现?我想这不仅对我有用。
    • @user1935987 我已根据您的要求添加并完善了上面的答案 - 希望这会有所帮助。
    • 啊,好吧,你的意思是使用input graphql 类型。可能误会你了。是的,这是一个可能的解决方案,但个人不想使用它,因为它会添加更多代码,尤其是对于较大的对象。
    猜你喜欢
    • 2019-05-12
    • 2017-09-22
    • 2020-05-05
    • 2020-09-22
    • 1970-01-01
    • 2018-06-20
    • 2018-05-22
    • 2018-02-22
    • 2018-07-15
    相关资源
    最近更新 更多