在go-graphql中,获取变量\“ $ address \”不能为非输入类型\“ String!\

时间:2018-12-24 18:47:04

标签: go graphql

我已经使用graphql-go库成功地设置了一个GraphQL服务器。但是,在进行查询时传递查询参数时,似乎出现了错误。因此,我有一个名为emails的查询,该查询以address作为参数,并查询数据库以返回有关与给定address关联的所有电子邮件的结果。当我直接传递address参数时,一切似乎都可以正常运行,如您从这张图片可以看到的:

enter image description here

但是,当我向它传递查询参数时,它似乎不起作用:

enter image description here

我不认为这两个语句应该给出相同的结果。但是,事实并非如此。有人可以帮助我了解为什么我会收到这些错误吗?这是我的执行代码

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 个答案:

答案 0 :(得分:1)

根据您看到的错误消息尚不清楚,但这可能是由于架构中重复的名称所致,如this Github issue中所述。您有两种类型,分别称为EmailemailTypedeleteEmailType。尝试重命名其中之一。