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 查询参数传递