Я успешно настроил сервер GraphQL в go, используя библиотеку graphql-go.Тем не менее, я, кажется, получаю сообщение об ошибке при передаче параметров запроса при создании запроса.Итак, у меня есть запрос с именем emails
, который принимает address
в качестве аргумента и запрашивает базу данных, чтобы вернуть результаты по всем электронным письмам, связанным с данным address
.Когда я передаю параметр address
напрямую, кажется, что все работает отлично, как вы можете видеть из этого изображения:
Однако это не такКажется, что он работает, когда я передаю ему параметры запроса, например:
Я был не уверен, что эти два оператора должны давать одинаковые результаты.Тем не менее, это не так.Может ли кто-нибудь помочь мне понять, почему я получаю эти ошибки?Это мой код доступа
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))
}