当前位置: 首页 > 知识库问答 >
问题:

Apollo/GraphQl-类型必须为输入类型

邰德业
2023-03-14

我正在学习Apollo和graphQL,并将其集成到我的一个项目中。到目前为止一切正常,但现在我正在尝试一些突变,我正在努力处理输入类型和查询类型。我觉得事情比实际情况要复杂得多,因此我正在寻求如何处理我的情况的建议。我在网上找到的示例都是非常基本的模式,但现实总是更加复杂,因为我的模式非常大,如下所示(我只复制一部分):

type Calculation {
    _id: String!
    userId: String!
    data: CalculationData
    lastUpdated: Int
    name: String
}

type CalculationData {
    Loads: [Load]
    validated: Boolean
    x: Float
    y: Float
    z: Float
    Inputs: [Input]
    metric: Boolean

}

然后定义输入和负载,依此类推...

为此,我需要一个变异来保存“计算”,因此在同一个文件中,我有以下内容:

type Mutation {
    saveCalculation(data: CalculationData!, name: String!): Calculation
}

我的解析器如下:

export default resolvers = {
    Mutation: {
        saveCalculation(obj, args, context) {
            if(context.user && context.user._id){
                const calculationId = Calculations.insert({
                    userId: context.user._id,
                    data: args.data,
                    name: args.name
                })
                return Calculations.findOne({ _id: calculationId})
            }
            throw new Error('Need an account to save a calculation')
        }
    }
}

那么我的突变如下:从'graph ql-tag'导入gql;

export const SAVE_CALCULATION = gql`
    mutation saveCalculation($data: CalculationData!, $name: String!){
        saveCalculation(data: $data, name: $name){
            _id
        }
    }
`

最后,我正在使用突变组件来尝试保存数据:

<Mutation mutation={SAVE_CALCULATION}>
    {(saveCalculation, { data }) => (
        <div onClick={() => saveCalculation({ variables : { data: this.state, name:'name calcul' }})}>SAVE</div>
    }}
</Mutation>

现在我得到以下错误:

[GraphQL错误]:消息:Mutation.save计算(data:)的类型必须是输入类型,但得到:计算数据!.,位置:未定义,路径:未定义

从我的研究和其他一些SO帖子中,我知道我应该在Query类型之外定义Input类型,但Input类型只能avec Scalar类型,但我的模式依赖于其他模式(这不是标量)。当最后一个只有标量类型时,我可以根据其他Input类型等创建Input类型吗?我有点迷茫,因为它似乎有很多冗余。非常感谢关于最佳实践的一些指导。我相信随着时间的推移,Apollo/graph ql可以为我的项目带来很好的帮助,但我不得不承认,当Schemas有点复杂时,实现它比我想象的要复杂。在线示例通常坚持使用字符串和布尔值。

共有2个答案

赵晨
2023-03-14

是的,您可以:

输入对象类型上的字段本身可以引用输入对象类型,但不能在模式中混合输入和输出类型。输入对象类型的字段上也不能有参数。

输入类型是在普通类型之外定义的。通常它们会有一些差异,例如输入没有id或createdAt字段。

谷梁子昂
2023-03-14

从规格:

字段可以接受参数来配置其行为。这些输入通常是标量或枚举,但有时需要表示更复杂的值。

GraphQL输入对象定义一组输入字段;输入字段可以是标量、枚举或其他输入对象。这允许参数接受任意复杂的结构。

换句话说,不能使用常规的GraphQLInputObjectType作为GraphQLInputObjectType字段的类型——必须使用另一个GraphQLInputObjectType。

当您使用SDL编写模式时,必须创建加载类型和加载输入,这似乎是多余的,尤其是当它们具有相同的字段时。然而,在后台,您定义的类型和输入被转换为非常不同的对象类,每个类都具有不同的属性和方法。有一些特定于GraphQLInputObjectType的功能(如接受参数),而GraphQLInputObjectType上不存在这些功能,反之亦然。

试图用另一个来代替另一个,有点像试图把一个方形的钉子放在一个圆孔里。“我不知道为什么我需要一个圆。我有一个正方形。它们都有直径。为什么我需要两者?”

除此之外,还有一个很好的实际原因,就是要将类型和输入分开。这是因为在很多情况下,您将在类型上公开大量字段,而不会在输入上公开这些字段。

例如,您的类型可能包括派生字段,这些字段实际上是基础数据的组合。或者它可能包括与其他数据的关系字段(例如用户上的朋友字段)。在这两种情况下,将这些字段作为作为某个字段的参数提交的数据的一部分是没有意义的。同样,您可能有一些不想在其类型对应项上公开的输入字段(想到的是密码字段)。

 类似资料:
  • 我使用laravel-graphql作为后端GraphQL服务,使用vue-apollo作为前端客户端。 在我的Vue组件中,我有一个gql查询,如下所示:(关系:一首歌有更多的歌曲部分) 现在有一个突变,我想用它来更新给定的歌曲:

  • 我正在使用Apollo Angular并托管一个GraphQL驱动的服务器。我试图实现的请求很简单。我需要传递一个对象作为我请求的查询参数。这是我的请求: 查询定义为: 服务器上的我的架构定义为: 当我的解析器功能 我想知道是否允许输入作为查询中的参数,如果不允许,我应该使用什么样的模式或实践。 如果可能,我不希望我的在代码中显式地包含每个参数。 非常感谢。 编辑:已解决,解析程序函数中的行为,从

  • 如果我更改为: 代码运行良好-但我想转换工作。

  • 我是GraphQL新手,在编写了一些代码之后,我遇到了一个问题,即为一个突变声明一个输入类型。以下是我的模式: 当我运行我的应用程序时,我得到了错误信息 原因:graphql。kickstart。工具。SchemaError:预期类型“IdInput”是GraphQLInputType,但事实并非如此!类型是否只允许对象类型被错误地用作输入类型,反之亦然?在graphql。kickstart。工具

  • 我正在这个名为Wertik JShttps://github.com/ilyaskarim/wertik-js库上工作,以使GraphQL Rest API更容易,在解析器中,当我控制台日志时,它显示未定义。对于每个模块,我都创建了动态解析器,让使用这个库的开发人员更容易。 行:https://github.com/ilyaskarim/wertik-js/blob/ec813f49a14ddd6

  • `从“React”导入React,{Component}; 从“react native”导入{样式表、平台、视图、图像、文本、TextInput、TouchableOpacity、Alert、YellowBox、ListView}; const Realm=require('Realm'); 让王国; 从响应导航导入{StackNavigator}; 扩展组件{ } 类ShowDataActiv