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

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

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

问题

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

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

  1. var fileDocumentType = graphql.NewObject(graphql.ObjectConfig{
  2. Name: "FileDocument",
  3. Fields: graphql.Fields{
  4. "id": &graphql.Field{
  5. Type: graphql.String,
  6. Resolve: func(p graphql.ResolveParams) (interface{}, error) {
  7. if fileDoc, ok := p.Source.(data_format.FileDocument); ok {
  8. return fileDoc.Id, nil
  9. }
  10. return "", nil
  11. },
  12. },
  13. "tags": &graphql.Field{
  14. Type: graphql.NewList(tagsDataType),
  15. Args: graphql.FieldConfigArgument{
  16. "tags": &graphql.ArgumentConfig{
  17. Type: tagsInputType,
  18. },
  19. },
  20. Resolve: func(p graphql.ResolveParams) (interface{}, error) {
  21. fmt.Println(p.Source)
  22. fmt.Println(p.Args)
  23. if fileDoc, ok := p.Source.(data_format.FileDocument); ok {
  24. return fileDoc.Tags, nil
  25. }
  26. return nil, nil
  27. },
  28. },
  29. },
  30. })

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

  1. var tagsInputType = graphql.NewInputObject(graphql.InputObjectConfig{
  2. Name: "tagsInput",
  3. Fields: graphql.Fields{
  4. "keyt": &graphql.Field{
  5. Type: graphql.String,
  6. },
  7. "valuet": &graphql.Field{
  8. Type: graphql.String,
  9. },
  10. },
  11. })

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

  1. {
  2. list(location:"blah",rule:"blah")
  3. {
  4. id,tags(tags:{keyt:"test",valuet:"test"})
  5. {
  6. key,
  7. value
  8. },
  9. {
  10. datacentre,
  11. handlerData
  12. {
  13. key,
  14. value
  15. }
  16. }
  17. }
  18. }

我得到了以下错误:

  1. wrong result, unexpected errors: [Argument "tags" has invalid value {keyt: "test", valuet: "test"}.
  2. In field "keyt": Unknown field.
  3. 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:

  1. var fileDocumentType = graphql.NewObject(graphql.ObjectConfig{
  2. Name: "FileDocument",
  3. Fields: graphql.Fields{
  4. "id": &graphql.Field{
  5. Type: graphql.String,
  6. Resolve: func(p graphql.ResolveParams) (interface{}, error) {
  7. if fileDoc, ok := p.Source.(data_format.FileDocument); ok {
  8. return fileDoc.Id, nil
  9. }
  10. return "", nil
  11. },
  12. },
  13. "tags": &graphql.Field{
  14. Type: graphql.NewList(tagsDataType),
  15. Args: graphql.FieldConfigArgument{
  16. "tags": &graphql.ArgumentConfig{
  17. Type: tagsInputType,
  18. },
  19. },
  20. Resolve: func(p graphql.ResolveParams) (interface{}, error) {
  21. fmt.Println(p.Source)
  22. fmt.Println(p.Args)
  23. if fileDoc, ok := p.Source.(data_format.FileDocument); ok {
  24. return fileDoc.Tags, nil
  25. }
  26. return nil, nil
  27. },
  28. },
  29. },
  30. })

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

  1. var tagsInputType = graphql.NewInputObject(graphql.InputObjectConfig{
  2. Name: "tagsInput",
  3. Fields: graphql.Fields{
  4. "keyt": &graphql.Field{
  5. Type: graphql.String,
  6. },
  7. "valuet": &graphql.Field{
  8. Type: graphql.String,
  9. },
  10. },
  11. })

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

  1. {
  2. list(location:"blah",rule:"blah")
  3. {
  4. id,tags(tags:{keyt:"test",valuet:"test"})
  5. {
  6. key,
  7. value
  8. },
  9. {
  10. datacentre,
  11. handlerData
  12. {
  13. key,
  14. value
  15. }
  16. }
  17. }
  18. }

I'm getting the following error:

  1. wrong result, unexpected errors: [Argument "tags" has invalid value {keyt: "test", valuet: "test"}.
  2. In field "keyt": Unknown field.
  3. 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应该像这样:

  1. var inputType = graphql.NewInputObject(
  2. graphql.InputObjectConfig{
  3. Name: "MyInputType",
  4. Fields: graphql.InputObjectConfigFieldMap{
  5. "key": &graphql.InputObjectFieldConfig{
  6. Type: graphql.String,
  7. },
  8. },
  9. },
  10. )

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

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "log"
  6. "github.com/graphql-go/graphql"
  7. )
  8. func main() {
  9. // Schema
  10. var inputType = graphql.NewInputObject(
  11. graphql.InputObjectConfig{
  12. Name: "MyInputType",
  13. Fields: graphql.InputObjectConfigFieldMap{
  14. "key": &graphql.InputObjectFieldConfig{
  15. Type: graphql.String,
  16. },
  17. },
  18. },
  19. )
  20. args := graphql.FieldConfigArgument{
  21. "foo": &graphql.ArgumentConfig{
  22. Type: inputType,
  23. },
  24. }
  25. fields := graphql.Fields{
  26. "hello": &graphql.Field{
  27. Type: graphql.String,
  28. Args: args,
  29. Resolve: func(p graphql.ResolveParams) (interface{}, error) {
  30. fmt.Println(p.Args)
  31. return "world", nil
  32. },
  33. },
  34. }
  35. rootQuery := graphql.ObjectConfig{
  36. Name: "RootQuery",
  37. Fields: fields,
  38. }
  39. schemaConfig := graphql.SchemaConfig{Query: graphql.NewObject(rootQuery)}
  40. schema, err := graphql.NewSchema(schemaConfig)
  41. if err != nil {
  42. log.Fatalf("failed to create new schema, error: %v", err)
  43. }
  44. // Query
  45. query := `
  46. {
  47. hello(foo:{key:"blah"})
  48. }
  49. `
  50. params := graphql.Params{Schema: schema, RequestString: query}
  51. r := graphql.Do(params)
  52. if len(r.Errors) > 0 {
  53. log.Fatalf("failed to execute graphql operation, errors: %+v", r.Errors)
  54. }
  55. rJSON, _ := json.Marshal(r)
  56. fmt.Printf("%s \n", rJSON) // {"data":{"hello":"world"}}
  57. }

以上是翻译好的内容。

英文:

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 :

  1. var inputType = graphql.NewInputObject(
  2. graphql.InputObjectConfig{
  3. Name: "MyInputType",
  4. Fields: graphql.InputObjectConfigFieldMap{
  5. "key": &graphql.InputObjectFieldConfig{
  6. Type: graphql.String,
  7. },
  8. },
  9. },
  10. )

Modified the Hello World example to take an Input Object :

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "log"
  6. "github.com/graphql-go/graphql"
  7. )
  8. func main() {
  9. // Schema
  10. var inputType = graphql.NewInputObject(
  11. graphql.InputObjectConfig{
  12. Name: "MyInputType",
  13. Fields: graphql.InputObjectConfigFieldMap{
  14. "key": &graphql.InputObjectFieldConfig{
  15. Type: graphql.String,
  16. },
  17. },
  18. },
  19. )
  20. args := graphql.FieldConfigArgument{
  21. "foo": &graphql.ArgumentConfig{
  22. Type: inputType,
  23. },
  24. }
  25. fields := graphql.Fields{
  26. "hello": &graphql.Field{
  27. Type: graphql.String,
  28. Args: args,
  29. Resolve: func(p graphql.ResolveParams) (interface{}, error) {
  30. fmt.Println(p.Args)
  31. return "world", nil
  32. },
  33. },
  34. }
  35. rootQuery := graphql.ObjectConfig{
  36. Name: "RootQuery",
  37. Fields: fields,
  38. }
  39. schemaConfig := graphql.SchemaConfig{Query: graphql.NewObject(rootQuery)}
  40. schema, err := graphql.NewSchema(schemaConfig)
  41. if err != nil {
  42. log.Fatalf("failed to create new schema, error: %v", err)
  43. }
  44. // Query
  45. query := `
  46. {
  47. hello(foo:{key:"blah"})
  48. }
  49. `
  50. params := graphql.Params{Schema: schema, RequestString: query}
  51. r := graphql.Do(params)
  52. if len(r.Errors) > 0 {
  53. log.Fatalf("failed to execute graphql operation, errors: %+v", r.Errors)
  54. }
  55. rJSON, _ := json.Marshal(r)
  56. fmt.Printf("%s \n", rJSON) // {“data”:{“hello”:”world”}}
  57. }

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:

确定