graphql-go:在查询中使用对象作为输入参数

huangapple go评论86阅读模式
英文:

graphql-go : Use an Object as Input Argument to a Query

问题

我正在尝试将一个对象作为参数传递给查询(而不是标量)。从文档中看,这应该是可能的,但我无法弄清楚如何使其工作。

我正在使用graphql-go,以下是测试模式:

var fileDocumentType = graphql.NewObject(graphql.ObjectConfig{
	Name: "FileDocument",
	Fields: graphql.Fields{
		"id": &graphql.Field{
			Type: graphql.String,
			Resolve: func(p graphql.ResolveParams) (interface{}, error) {
				if fileDoc, ok := p.Source.(data_format.FileDocument); ok {
					return fileDoc.Id, nil
				}
				return "", nil
			},
		},
		"tags": &graphql.Field{
			Type: graphql.NewList(tagsDataType),
			Args: graphql.FieldConfigArgument{
				"tags": &graphql.ArgumentConfig{
					Type: tagsInputType,
				},
			},
			Resolve: func(p graphql.ResolveParams) (interface{}, error) {
				fmt.Println(p.Source)
				fmt.Println(p.Args)
				if fileDoc, ok := p.Source.(data_format.FileDocument); ok {
					return fileDoc.Tags, nil
				}
				return nil, nil
			},
		},
	},
})

我尝试使用的输入类型(我尝试过InputObject和标准Object)如下:

var tagsInputType = graphql.NewInputObject(graphql.InputObjectConfig{
	Name: "tagsInput",
	Fields: graphql.Fields{
		"keyt": &graphql.Field{
			Type: graphql.String,
		},
		"valuet": &graphql.Field{
			Type: graphql.String,
		},
	},
})

这是我用来测试的GraphQL查询:

{
	list(location:"blah",rule:"blah")
	{
		id,tags(tags:{keyt:"test",valuet:"test"})
		{
			key,
			value
		},
		{
			datacentre,
			handlerData
			{
				key,
				value
			}
		}
	}
}

我得到了以下错误:

wrong result, unexpected errors: [Argument "tags" has invalid value {keyt: "test", valuet: "test"}.
In field "keyt": Unknown field.
In field "valuet": Unknown field.]

问题是,当我将类型更改为字符串时,它可以正常工作。我该如何将对象用作输入参数?

谢谢!

英文:

I'm attempting to pass an object as an argument to a query (rather than a scalar). From the docs it seems that this should be possible, but I can't figure out how to make it work.

I'm using graphql-go, here is the test schema:

var fileDocumentType = graphql.NewObject(graphql.ObjectConfig{
Name: "FileDocument",
Fields: graphql.Fields{
	"id": &graphql.Field{
		Type: graphql.String,
		Resolve: func(p graphql.ResolveParams) (interface{}, error) {
			if fileDoc, ok := p.Source.(data_format.FileDocument); ok {
				return fileDoc.Id, nil
			}
			return "", nil
		},
	},
	"tags": &graphql.Field{
		Type: graphql.NewList(tagsDataType),
		Args: graphql.FieldConfigArgument{
			"tags": &graphql.ArgumentConfig{
				Type: tagsInputType,
			},
		},
		Resolve: func(p graphql.ResolveParams) (interface{}, error) {
			fmt.Println(p.Source)
			fmt.Println(p.Args)
			if fileDoc, ok := p.Source.(data_format.FileDocument); ok {
				return fileDoc.Tags, nil
			}
			return nil, nil
		},
	},

},
})

And the inputtype I'm attempting to use (I've tried both an InputObject and a standard Object)

var tagsInputType = graphql.NewInputObject(graphql.InputObjectConfig{
Name: "tagsInput",
Fields: graphql.Fields{
	"keyt": &graphql.Field{
		Type: graphql.String,
	},
	"valuet": &graphql.Field{
		Type: graphql.String,
	},
},
})

And here is the graphql query I'm using to test:

{
		list(location:"blah",rule:"blah")
		{
			id,tags(tags:{keyt:"test",valuet:"test"})
			{
				key,
				value
			},
			{
				datacentre,
				handlerData
				{
					key,
					value
				}
			}
		}
	}

I'm getting the following error:

wrong result, unexpected errors: [Argument "tags" has invalid value {keyt: "test", valuet: "test"}.
In field "keyt": Unknown field.
In field "valuet": Unknown field.]

The thing is, when I change the type to a string, it works fine. How do I use an object as an input arg?

Thanks!

答案1

得分: 38

遇到了同样的问题。通过查看graphql-go源代码,我找到了解决方法。

InputObjectFields必须是InputObjectConfigFieldMapInputObjectConfigFieldMapThunk类型,才能正常工作。

所以一个InputObject应该像这样:

var inputType = graphql.NewInputObject(
	graphql.InputObjectConfig{
		Name: "MyInputType",
		Fields: graphql.InputObjectConfigFieldMap{
			"key": &graphql.InputObjectFieldConfig{
				Type: graphql.String,
			},
		},
	},
)

修改了Hello World示例,使用了Input Object

package main

import (
	"encoding/json"
	"fmt"
	"log"

	"github.com/graphql-go/graphql"
)

func main() {
	// Schema

	var inputType = graphql.NewInputObject(
		graphql.InputObjectConfig{
			Name: "MyInputType",
			Fields: graphql.InputObjectConfigFieldMap{
				"key": &graphql.InputObjectFieldConfig{
					Type: graphql.String,
				},
			},
		},
	)

	args := graphql.FieldConfigArgument{
		"foo": &graphql.ArgumentConfig{
			Type: inputType,
		},
	}

	fields := graphql.Fields{
		"hello": &graphql.Field{
			Type: graphql.String,
			Args: args,
			Resolve: func(p graphql.ResolveParams) (interface{}, error) {
				fmt.Println(p.Args)
				return "world", nil
			},
		},
	}
	rootQuery := graphql.ObjectConfig{
		Name:   "RootQuery",
		Fields: fields,
	}

	schemaConfig := graphql.SchemaConfig{Query: graphql.NewObject(rootQuery)}
	schema, err := graphql.NewSchema(schemaConfig)
	if err != nil {
		log.Fatalf("failed to create new schema, error: %v", err)
	}

	// Query
	query := `
		{
			hello(foo:{key:"blah"})
		}
	`
	params := graphql.Params{Schema: schema, RequestString: query}
	r := graphql.Do(params)
	if len(r.Errors) > 0 {
		log.Fatalf("failed to execute graphql operation, errors: %+v", r.Errors)
	}
	rJSON, _ := json.Marshal(r)
	fmt.Printf("%s \n", rJSON) // {"data":{"hello":"world"}}
}

以上是翻译好的内容。

英文:

Had the same issue. Here is what I found from going through the graphql-go source.

The Fields of an InputObject have to be of type InputObjectConfigFieldMap or InputObjectConfigFieldMapThunk for the pkg to work.

So an InputObject would look like this :

var inputType = graphql.NewInputObject(
graphql.InputObjectConfig{
Name: "MyInputType",
Fields: graphql.InputObjectConfigFieldMap{
"key": &graphql.InputObjectFieldConfig{
Type: graphql.String,
},
},
},
) 

Modified the Hello World example to take an Input Object :

package main
import (
"encoding/json"
"fmt"
"log"
"github.com/graphql-go/graphql"
)
func main() {
// Schema
var inputType = graphql.NewInputObject(
graphql.InputObjectConfig{
Name: "MyInputType",
Fields: graphql.InputObjectConfigFieldMap{
"key": &graphql.InputObjectFieldConfig{
Type: graphql.String,
},
},
},
)
args := graphql.FieldConfigArgument{
"foo": &graphql.ArgumentConfig{
Type: inputType,
},
}
fields := graphql.Fields{
"hello": &graphql.Field{
Type: graphql.String,
Args: args,
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
fmt.Println(p.Args)
return "world", nil
},
},
}
rootQuery := graphql.ObjectConfig{
Name:   "RootQuery",
Fields: fields,
}
schemaConfig := graphql.SchemaConfig{Query: graphql.NewObject(rootQuery)}
schema, err := graphql.NewSchema(schemaConfig)
if err != nil {
log.Fatalf("failed to create new schema, error: %v", err)
}
// Query
query := `
{
hello(foo:{key:"blah"})
}
`
params := graphql.Params{Schema: schema, RequestString: query}
r := graphql.Do(params)
if len(r.Errors) > 0 {
log.Fatalf("failed to execute graphql operation, errors: %+v", r.Errors)
}
rJSON, _ := json.Marshal(r)
fmt.Printf("%s \n", rJSON) // {“data”:{“hello”:”world”}}
}

huangapple
  • 本文由 发表于 2016年11月1日 21:21:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/40360936.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定