graphql-go / graphql

An implementation of GraphQL for Go / Golang
MIT License
9.87k stars 839 forks source link

Request with multiarrays #548

Closed Fruchtgummi closed 4 years ago

Fruchtgummi commented 4 years ago

I want send a request to a struct with multiple structs.

my request.

{
  "operationName":"myoperation",
  "variables":{"vorgangsnumer":"","haushalt":["antragssteller":["vorname":"Karl-Heinz", "nachname":"Peter"]]},
  "query":"mutation Myoperation($vorgangsnumer: String!,$haushalt[$antragssteller[$vorname: String!,$nachname: String!]]) {setProcess(vorgangsnummer:$vorgangsnumer,haushalt:$haushalt){vorgangsNummer}}"
}

I don't unterstand the request with multiple-arrays.

Please help!

chris-ramon commented 4 years ago

Hi @Fruchtgummi, thanks for using the lib, in order to send multiple structs wrapped as a variable the recommended way is to use Input types which can be used via: NewInputObject, next sharing a working example:

package main

import (
    "encoding/json"
    "log"

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

var RootQuery = graphql.NewObject(graphql.ObjectConfig{
    Name: "RootQuery",
    Fields: graphql.Fields{
        "noop": &graphql.Field{
            Type: graphql.String,
        },
    },
})

type Antragssteller struct {
    Vorname  string
    Nachname string
}

type Process struct {
    VorgangsNummer string
    Antragssteller Antragssteller
}

var ProcessType = graphql.NewObject(graphql.ObjectConfig{
    Name: "ProcessType",
    Fields: graphql.Fields{
        "vorgangsNummer": &graphql.Field{
            Type: graphql.String,
        },
    },
})

var AntragsstellerInputType = graphql.NewInputObject(
    graphql.InputObjectConfig{
        Name: "AntragsstellerInputType",
        Fields: graphql.InputObjectConfigFieldMap{
            "vorname": &graphql.InputObjectFieldConfig{
                Type: graphql.String,
            },
            "nachname": &graphql.InputObjectFieldConfig{
                Type: graphql.String,
            },
        },
    },
)

var HaushaltInputType = graphql.NewInputObject(
    graphql.InputObjectConfig{
        Name: "HaushaltInputType",
        Fields: graphql.InputObjectConfigFieldMap{
            "antragssteller": &graphql.InputObjectFieldConfig{
                Type: AntragsstellerInputType,
            },
        },
    },
)

var RootMutation = graphql.NewObject(graphql.ObjectConfig{
    Name: "RootMutation",
    Fields: graphql.Fields{
        "setProcess": &graphql.Field{
            Args: graphql.FieldConfigArgument{
                "vorgangsnummer": &graphql.ArgumentConfig{
                    Type: graphql.String,
                },
                "haushalt": &graphql.ArgumentConfig{
                    Type: HaushaltInputType,
                },
            },
            Type: ProcessType,
            Resolve: func(p graphql.ResolveParams) (interface{}, error) {
                haushalt := p.Args["haushalt"].(map[string]interface{})
                antragssteller := haushalt["antragssteller"].(map[string]interface{})

                process := Process{
                    VorgangsNummer: p.Args["vorgangsnummer"].(string),
                    Antragssteller: Antragssteller{
                        Vorname:  antragssteller["vorname"].(string),
                        Nachname: antragssteller["nachname"].(string),
                    },
                }

                log.Printf("process: %+v", process) // 2020/06/14 20:16:30 process: {VorgangsNummer:1234 Antragssteller:{Vorname:vorname 123 Nachname:nachname 456}}

                return process, nil
            },
        },
    },
})

func main() {
    schema, err := graphql.NewSchema(graphql.SchemaConfig{
        Query:    RootQuery,
        Mutation: RootMutation,
    })
    if err != nil {
        log.Fatal(err)
    }

    query := `
        mutation Myoperation {
          setProcess(vorgangsnummer: "1234", haushalt: {
            antragssteller: {
              vorname: "vorname 123",
              nachname: "nachname 456",
            }
          }) {
            vorgangsNummer
          }
        }
    `

    result := graphql.Do(graphql.Params{
        Schema:        schema,
        RequestString: query,
    })

    resultStr, err := json.Marshal(result)

    if err != nil {
        log.Fatal(err)
    }

    log.Println(string(resultStr)) // 2020/06/14 20:16:30 {"data":{"setProcess":{"vorgangsNummer":"1234"}}}
}
Fruchtgummi commented 4 years ago

Hi, Thank you. It is in going

I tried to push on the struct right away.

haushalt := p.Args["haushalt"].(mystruct)

chris-ramon commented 4 years ago

@Fruchtgummi glad it is working! –– should the issue be closed ?

Fruchtgummi commented 4 years ago

How do I get the request into Graphql-JSON?

{
  "operationName":"Myoperation",
  "variables":{
    "vorgangsnumer":"1234",
    "haushalt":
      {
        "antragssteller":[{
          "vorname":"Peter",
          "nachname":"Smith"
        }]
      }
  },
  "query":"mutation Myoperation($vorgangsnumer: String!,$haushalt:{$antragssteller:[{$vorname: String!,$nachname: String!}]!}) {setProcess(vorgangsnummer:$vorgangsnumer,haushalt:$haushalt{antragssteller:$antragssteller}){vorgangsNummer}}"
}

Error:


Syntax Error GraphQL request (1:69) Expected $, found {\n\n1: mutation Myoperation($vorgangsnumer: String!,$haushalt:[antragssteller:{$vorname: String!,$nachname: String!}]!) {setProcess(vorgangsnummer:$vorgangsnumer,haushalt:{$haushalt}){vorgangsNummer}}\n                                                                       ^\n",
"locations":[
{"line": 1, "column": 69}
]
}
]
}