Getting Variable \\“$address\\” cannot be non-inpu

2019-08-25 17:58发布

问题:

I've successfully set up a GraphQL server in go using the graphql-go library. However, I seem to be getting an error when I pass query parameters when making a query. So I have a query named emails that takes address as an argument and queries a database to return results regarding all the emails associated with the given address. When I pass the address parameter directly, everything seems to work perfectly, as you can see from this image:

However, it doesn't seem to work when I pass it query parameters, like this:

I was off the idea that these two statements should give the same results. However, this doesn't seem to be the case. Could somebody help me understand why I'm getting these errors? This is my go code

package main

import (
    "log"
    "net/http"

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

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/credentials"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/dynamodb"
    "github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute"
)

var sess, _ = session.NewSession()

// Email - Used to represent a single email object stored in
// dynamodb. Fields 'attachments', 'body-html', 'stripped-html' and
// 'stripped-text' may be empty.
type Email struct {
    To           string   `json:"to"`
    Recipients   []string `json:"recipients"`
    Token        string   `json:"token"`
    Sender       string   `json:"sender"`
    Subject      string   `json:"subject"`
    Timestamp    string   `json:"timestamp"`
    Attachments  []string `json:"attachments"`
    Mime         string   `json:"mime"`
    BodyPlain    string   `json:"body_plain"`
    BodyHTML     string   `json:"body_html"`
    StrippedText string   `json:"stripped_text"`
    StrippedHTML string   `json:"stripped_html"`
}

// emailType - a new graphql object representing a single email
var emailType = graphql.NewObject(graphql.ObjectConfig{
    Name: "Email",
    Fields: graphql.Fields{
        "to": &graphql.Field{
            Type: graphql.String,
        },
        "recipients": &graphql.Field{
            Type: graphql.NewList(graphql.String),
        },
        "token": &graphql.Field{
            Type: graphql.String,
        },
        "sender": &graphql.Field{
            Type: graphql.String,
        },
        "subject": &graphql.Field{
            Type: graphql.String,
        },
        "attachments": &graphql.Field{
            Type: graphql.NewList(graphql.String),
        },
        "timestamp": &graphql.Field{
            Type: graphql.String,
        },
        "mime": &graphql.Field{
            Type: graphql.String,
        },
        "body_plain": &graphql.Field{
            Type: graphql.String,
        },
        "body_html": &graphql.Field{
            Type: graphql.String,
        },
        "stripped_text": &graphql.Field{
            Type: graphql.String,
        },
        "stripped_html": &graphql.Field{
            Type: graphql.String,
        },
    },
})

// emailType - a new graphql object representing a deleted email.
var deleteEmailType = graphql.NewObject(graphql.ObjectConfig{
    Name: "Email",
    Fields: graphql.Fields{
        "to": &graphql.Field{
            Type: graphql.String,
        },
        "token": &graphql.Field{
            Type: graphql.String,
        },
    },
})

func disableCors(h http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Access-Control-Allow-Origin", "*")
        w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
        w.Header().Set("Access-Control-Allow-Headers", "Accept, Authorization, Content-Type, Content-Length, Accept-Encoding")

        // I added this for another handler of mine,
        // but I do not think this is necessary for GraphQL's handler
        if r.Method == "OPTIONS" {
            w.Header().Set("Access-Control-Max-Age", "86400")
            w.WriteHeader(http.StatusOK)
            return
        }

        h.ServeHTTP(w, r)
    })
}

func main() {
    // configures the rootQuery for the graphQL API
    rootQuery := graphql.NewObject(graphql.ObjectConfig{
        Name: "Query",
        Fields: graphql.Fields{
            "emails": &graphql.Field{
                Type: graphql.NewList(emailType),
                Args: graphql.FieldConfigArgument{
                    "address": &graphql.ArgumentConfig{
                        Type: graphql.String,
                    },
                },
                Resolve: func(params graphql.ResolveParams) (interface{}, error) {
                    address := params.Args["address"].(string)
                    svc := dynamodb.New(sess)
                    result, err := svc.Query(&dynamodb.QueryInput{
                        TableName: aws.String("emails_db"),
                        KeyConditions: map[string]*dynamodb.Condition{
                            "to": {
                                ComparisonOperator: aws.String("EQ"),
                                AttributeValueList: []*dynamodb.AttributeValue{
                                    {
                                        S: aws.String(address),
                                    },
                                },
                            },
                        },
                    })
                    if err != nil {
                        return nil, nil
                    }

                    // unmarshalls all the emails to recs
                    recs := []Email{}
                    err = dynamodbattribute.UnmarshalListOfMaps(result.Items, &recs)
                    if err != nil {
                        return nil, nil
                    }
                    return recs, nil
                },
            },
        },
    })

    // configures the rootMutation for the graphQL API
    rootMutation := graphql.NewObject(graphql.ObjectConfig{
        Name: "Mutation",
        Fields: graphql.Fields{
            "email": &graphql.Field{
                Type: deleteEmailType,
                Args: graphql.FieldConfigArgument{
                    "address": &graphql.ArgumentConfig{
                        Type: graphql.NewNonNull(graphql.String),
                    },
                    "token": &graphql.ArgumentConfig{
                        Type: graphql.NewNonNull(graphql.String),
                    },
                },
                Resolve: func(params graphql.ResolveParams) (interface{}, error) {
                    address := params.Args["address"].(string)
                    token := params.Args["token"].(string)
                    svc := dynamodb.New(sess)
                    _, err := svc.DeleteItem(&dynamodb.DeleteItemInput{
                        TableName: aws.String("emails_db"),
                        Key: map[string]*dynamodb.AttributeValue{
                            "to": {
                                S: aws.String(address),
                            },
                            "token": {
                                S: aws.String(token),
                            },
                        },
                    })
                    if err != nil {
                        return nil, err
                    }

                    // unmarshalls all the emails to recs
                    rec := Email{To: address, Token: token}
                    return rec, nil
                },
            },
        },
    })

    // configures routes
    schema, _ := graphql.NewSchema(graphql.SchemaConfig{
        Mutation: rootMutation,
        Query:    rootQuery,
    })
    h := handler.New(&handler.Config{
        Schema:   &schema,
        Pretty:   true,
        GraphiQL: true,
    })
    http.Handle("/graphql", disableCors(h))
    log.Fatal(http.ListenAndServe(":80", nil))
}

回答1:

It's not clear from the error message you're seeing, but it could be due to the duplicate names in your schema, as outlined in this Github issue. You have two types called Email -- emailType and deleteEmailType. Try renaming one of them.



标签: go graphql