英文:
Error when trying to query neo4j database using golang and graphql
问题
我尝试使用neo4j数据库创建一个简单的graphql和go服务器,但是我一直遇到这个错误:
{
"data": {
"movieByTitle": null
},
"errors": [
{
"message": "User Error: expected iterable, but did not find one for field Query.movieByTitle.",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"movieByTitle"
]
}
]
}
当我发起请求时出现这个错误。这是我的graphql字段:
var getMovieByTitle = &graphql.Field{
Type: graphql.NewList(models.MovieType),
Args: graphql.FieldConfigArgument{
"title": &graphql.ArgumentConfig{
Type: graphql.String,
},
},
Resolve: func(params graphql.ResolveParams) (interface{}, error) {
title := params.Args["title"].(string)
configuration := data.ParseConfiguration()
driver, err := configuration.NewDriver()
if err != nil {
log.Fatal(err)
}
defer data.UnsafeClose(driver)
session := driver.NewSession(neo4j.SessionConfig{
AccessMode: neo4j.AccessModeRead,
DatabaseName: configuration.Database,
})
defer data.UnsafeClose(session)
movie, err := session.ReadTransaction(func(tx neo4j.Transaction) (interface{}, error) {
records, err := tx.Run(
`MATCH (movie:Movie {title:$title})
OPTIONAL MATCH (movie)<-[r]-(person:Person)
WITH movie.title as title,
collect({name:person.name,
job:head(split(toLower(type(r)),'_')),
role:r.roles}) as cast
LIMIT 1
UNWIND cast as c
RETURN title, c.name as name, c.job as job, c.role as role`,
map[string]interface{}{"title": title})
if err != nil {
return nil, err
}
var result models.Movie
for records.Next() {
record := records.Record()
title, _ := record.Get("title")
result.Title = title.(string)
name, _ := record.Get("name")
job, _ := record.Get("job")
role, _ := record.Get("role")
switch role.(type) {
case []interface{}:
result.Cast = append(result.Cast, models.Person{Name: name.(string), Job: job.(string), Role: data.ToStringSlice(role.([]interface{}))})
default: // handle nulls or unexpected stuff
result.Cast = append(result.Cast, models.Person{Name: name.(string), Job: job.(string)})
}
}
return result, nil
})
if movie == nil {
log.Println(movie)
return nil, fmt.Errorf("movie not found")
}
fmt.Println(movie)
return movie, nil
},
}
我正在使用gin来运行服务器。我尝试使用http端点而不是graphql运行相同的查询,并获得了预期的响应。我该如何修复这个错误?我正在使用neo4j中的示例电影数据集。
英文:
I tried making a simple server for graphql and go using a neo4j database but I keep getting this error:
{
"data": {
"movieByTitle": null
},
"errors": [
{
"message": "User Error: expected iterable, but did not find one for field Query.movieByTitle.",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"movieByTitle"
]
}
]
}
when I make a request. This is my graphql field:
var getMovieByTitle = &graphql.Field{
Type: graphql.NewList(models.MovieType),
Args: graphql.FieldConfigArgument{
"title": &graphql.ArgumentConfig{
Type: graphql.String,
},
},
Resolve: func(params graphql.ResolveParams) (interface{}, error) {
title := params.Args["title"].(string)
configuration := data.ParseConfiguration()
driver, err := configuration.NewDriver()
if err != nil {
log.Fatal(err)
}
defer data.UnsafeClose(driver)
session := driver.NewSession(neo4j.SessionConfig{
AccessMode: neo4j.AccessModeRead,
DatabaseName: configuration.Database,
})
defer data.UnsafeClose(session)
movie, err := session.ReadTransaction(func(tx neo4j.Transaction) (interface{}, error) {
records, err := tx.Run(
`MATCH (movie:Movie {title:$title})
OPTIONAL MATCH (movie)<-[r]-(person:Person)
WITH movie.title as title,
collect({name:person.name,
job:head(split(toLower(type(r)),'_')),
role:r.roles}) as cast
LIMIT 1
UNWIND cast as c
RETURN title, c.name as name, c.job as job, c.role as role`,
map[string]interface{}{"title": title})
if err != nil {
return nil, err
}
var result models.Movie
for records.Next() {
record := records.Record()
title, _ := record.Get("title")
result.Title = title.(string)
name, _ := record.Get("name")
job, _ := record.Get("job")
role, _ := record.Get("role")
switch role.(type) {
case []interface{}:
result.Cast = append(result.Cast, models.Person{Name: name.(string), Job: job.(string), Role: data.ToStringSlice(role.([]interface{}))})
default: // handle nulls or unexpected stuff
result.Cast = append(result.Cast, models.Person{Name: name.(string), Job: job.(string)})
}
}
return result, nil
})
if movie == nil {
log.Println(movie)
return nil, fmt.Errorf("movie not found")
}
fmt.Println(movie)
return movie, nil
},
}
I am using gin to run the server. I tried running the same query with an http endpoint instead of graphql and I got the expected response. How can I fix the error? I am using the example movie dataset in neo4j.
答案1
得分: 1
看起来Query.movieByTitle
字段的类型是一个Movie对象的数组,但是你的解析器返回的是单个电影而不是列表/数组。
在其他GraphQL服务器实现中,通常会优雅地处理这个问题,不确定你正在使用的Go GraphQL实现是否也是如此。
英文:
It looks like the type of the Query.movieByTitle
field is an array of Movie objects, but is your resolver returning a single movie instead of a list/array?
In other GraphQL server implementations, this is typically handled gracefully, not sure about the Go GraphQL implementation you're using.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论