GraphQL - 使用对象作为参数

Posted

技术标签:

【中文标题】GraphQL - 使用对象作为参数【英文标题】:GraphQL - Use Object as argument 【发布时间】:2021-06-04 23:20:07 【问题描述】:

我正在使用 GraphQL 构建 API,API 的选项之一是下订单

我使用 Go 1.16 和 graphql-go 作为 GraphQL 后端

PlaceOrder API 调用的 JSON 格式为:


   "order_reference":"unique order reference",
   "customer_order_reference":"customer order reference",
   "email_address":"email@example.com",
   "phone_number":"0123456789",
   "billing_address":
      "name":"Billing name",
      "address_line_one":"Billing line one",
      "address_line_two":"Billing line two",
      "address_line_three":"Billing line three",
      "address_line_four":"Billing line four",
      "postcode":"billing postcode"
   ,
   "delivery_address":
      "name":"Delivery name",
      "address_line_one":"Delivery line one",
      "address_line_two":"Delivery line two",
      "address_line_three":"Delivery line three",
      "address_line_four":"Delivery line four",
      "postcode":"Delivery postcode"
   ,
   "order_lines":[
      
         "product_code":"123456",
         "quantity":1
      ,
      
         "product_code":"654321",
         "quantity":2
      
   ]

在 Go 代码中,我将架构字段设置为:

graphql.Fields
        "placeOrder": &graphql.Field
            Type: order.PlaceOrder(),
            Args: graphql.FieldConfigArgument
                "order_reference": &graphql.ArgumentConfig
                    Type: graphql.String,
                ,
                "customer_order_reference": &graphql.ArgumentConfig
                    Type: graphql.String,
                ,
                "email_address": &graphql.ArgumentConfig
                    Type: graphql.String,
                ,
                "phone_number": &graphql.ArgumentConfig
                    Type: graphql.String,
                ,
                "billing_address": &graphql.ArgumentConfig
                    Type: graphql.NewObject(
                        graphql.ObjectConfig
                            Name: "BillingAddress",
                            Fields: graphql.Fields
                                "name": &graphql.Field
                                    Type: graphql.String,
                                ,
                                "address_line_one": &graphql.Field
                                    Type: graphql.String,
                                ,
                                "address_line_two": &graphql.Field
                                    Type: graphql.String,
                                ,
                                "address_line_three": &graphql.Field
                                    Type: graphql.String,
                                ,
                                "address_line_four": &graphql.Field
                                    Type: graphql.String,
                                ,
                                "postcode": &graphql.Field
                                    Type: graphql.String,
                                ,
                            ,
                        ,
                    ),
                ,
                "delivery_address": &graphql.ArgumentConfig
                    Type: graphql.NewObject(
                        graphql.ObjectConfig
                            Name: "DeliveryAddress",
                            Fields: graphql.Fields
                                "name": &graphql.Field
                                    Type: graphql.String,
                                ,
                                "address_line_one": &graphql.Field
                                    Type: graphql.String,
                                ,
                                "address_line_two": &graphql.Field
                                    Type: graphql.String,
                                ,
                                "address_line_three": &graphql.Field
                                    Type: graphql.String,
                                ,
                                "address_line_four": &graphql.Field
                                    Type: graphql.String,
                                ,
                                "postcode": &graphql.Field
                                    Type: graphql.String,
                                ,
                            ,
                        ,
                    ),
                ,
                "order_lines": &graphql.ArgumentConfig
                    Type: graphql.NewList(graphql.NewObject(
                        graphql.ObjectConfig
                            Name: "Line",
                            Fields: graphql.Fields
                                "part_number": &graphql.Field
                                    Type: graphql.String,
                                ,
                                "quantity": &graphql.Field
                                    Type: graphql.String,
                                ,
                            ,
                        ,
                    )),
                ,
            ,
            Resolve: func(p graphql.ResolveParams) (interface, error) 
                // Code to interact with Database and assign value to status, reference depending on result of database INSERT and return as "response"
                return response, nil
            ,
        ,
    

我尝试了几种不同的方式将数据传递到地址和订单行,但似乎无法成功通过:例如,我尝试了以下方法,map[] 是 @ 的结果987654325@

查询:


    placeOrder(
        order_reference:"order reference"
        customer_order_reference: "cust order reference"
        billing_address: 
           name: "Billing Name"
           address_line_one: "Address line one"
           address_line_two: "Address line one"
           address_line_three: "Address line one"
           address_line_four: "Address line one"
           postcode: "Post code"
        
        delivery_address: 
           name: "Delivery Name"
           address_line_one: "Address line one"
           address_line_two: "Address line one"
           address_line_three: "Address line one"
           address_line_four: "Address line one"
           postcode: "Post code"
        
        order_lines: [
            
                part_number: "123456"
                quantity: 1
            
        ]
        )
            status,
            reference
        

结果:

map[
customer_order_reference:cust order reference
order_lines:[<nil>]
order_reference:order reference
]

【问题讨论】:

graphql-go 中没有 args 类型验证?真可惜......数量定义为字符串......将所有这些参数包装成一些input: createOrderInput类型 ***.com/a/41230015/6124657 @xadm - 非常感谢 【参考方案1】:

@xadm 提供的答案

https://***.com/a/41230015/6124657 中突出显示的解决方案

var InputType = graphql.NewInputObject(
    graphql.InputObjectConfig
        Name: "InputTypeName",
        Fields: graphql.InputObjectConfigFieldMap
            "sub_field_one": &graphql.InputObjectFieldConfig
                Type: graphql.String,
            ,
            "sub_field_two": &graphql.InputObjectFieldConfig
                Type: graphql.String,
            ,
        ,
    ,
)

在 Args 部分将原来的 NewObject(...) 替换为 NewInputObject(...)

"billing_address": &graphql.ArgumentConfig
                Type: graphql.NewInputObject(
                    graphql.InputObjectConfig
                        Name: "BillingAddress",
                        Fields: graphql.InputObjectConfigFieldMap
                            "address_line_one": &graphql.InputObjectFieldConfig
                                Type: graphql.String,
                            ,
                            "address_line_two": &graphql.InputObjectFieldConfig
                                Type: graphql.String,
                            ,
                           ...
                        ,
                    ,
                ),
            ,

这会生成一个包含子字段的地图

【讨论】:

以上是关于GraphQL - 使用对象作为参数的主要内容,如果未能解决你的问题,请参考以下文章

GraphQL.js Node/Express:如何将对象作为 GraphQL 查询参数传递

如何使用相同的参数查询 Graphql 2 对象

如何将具有多个对象的状态数组作为参数传递给graphql突变?

在 graphQL 中提交对象数组作为查询变量

在 Graphql 中使用枚举作为查询参数

如何使用参数创建 GraphQL 对象?