I'm very new to graphQL so I'm trying to create an api using library "gqlgen". But I faced with the problem.
I have 2 tables: user and balance which are related by one-to-one relationship, so I want to get balance nested in user model in response. But GetBalanceResolver method are not even called.
So here's my schema:
type User {
id: Int!
firstname: String!
lastname: String!
phoneNumber: String!
balance: Balance
}
type Query {
getUser(id: Int!): User
getBalance(id: Int!): Balance
}
type Balance {
id: Int!
balanceValue: Float!
}
Here's resolver:
type Resolver struct {
Repo *UserRepo
}
// GetUser is the resolver for the getUser field.
func (r *queryResolver) GetUser(ctx context.Context, id int) (*model.User, error) {
user := r.Repo.GetUser(int64(id))
log.Println("hello")
return &model.User{
ID: int(user.Id),
Firstname: user.Firstname,
Lastname: user.Lastname,
PhoneNumber: user.PhoneNumber,
}, nil
}
// GetBalance is the resolver for the getBalance field.
func (r *queryResolver) GetBalance(ctx context.Context, id int) (*model.Balance, error) {
balance := r.Repo.GetBalance(int64(id))
return &model.Balance{
ID: int(balance.Id),
BalanceValue: balance.BalanceValue,
}, nil
}
// Query returns QueryResolver implementation.
func (r *Resolver) Query() QueryResolver {
return &queryResolver{r}
}
type queryResolver struct{ *Resolver }
type mutationResolver struct {
*Resolver
}
Here's userRepo:
type IUserRepo interface {
GetUser(uid int64) *models.UserModel
}
type UserRepo struct {
}
func (r *UserRepo) GetUser(uid int64) *models.UserModel {
fmt.Println(uid)
user := &models.UserModel{}
query := `SELECT user_id, firstname, lastname, phone_number FROM user_schema.user_account WHERE user_id = $1`
err := constant.Db.QueryRowContext(context.Background(), query, uid).Scan(&user.Id, &user.Firstname, &user.Lastname, &user.PhoneNumber)
if err != nil {
panic(err)
}
return user
}
func (r *UserRepo) GetBalance(bid int64) *models.BalanceModel {
balance := &models.BalanceModel{}
query := `SELECT balance_id, balance_value FROM user_schema.balance WHERE user_id = $1`
rows, err := constant.Db.Query(query, bid)
if err != nil {
panic(err)
}
rows.Scan(&balance.Id, &balance.BalanceValue)
if err := rows.Err(); err != nil {
panic(err)
}
return balance
}
And here's the gqlgen.yml:
schema:
- graph/*.graphqls
exec:
filename: graph/generated.go
package: graph
model:
filename: graph/model/models_gen.go
package: model
resolver:
layout: follow-schema
dir: graph
package: graph
filename_template: "{name}.resolvers.go"
models:
ID:
model:
- github.com/99designs/gqlgen/graphql.ID
- github.com/99designs/gqlgen/graphql.Int
- github.com/99designs/gqlgen/graphql.Int64
- github.com/99designs/gqlgen/graphql.Int32
Int:
model:
- github.com/99designs/gqlgen/graphql.Int
- github.com/99designs/gqlgen/graphql.Int64
- github.com/99designs/gqlgen/graphql.Int32
And here's the request that I provide in graphql playground:
query {
getUser(id: 1) {
firstname,
lastname,
balance {
id,
balanceValue
}
}
}
Response:
{
"data": {
"getUser": {
"firstname": "vvvvv",
"lastname": "aaaa",
"balance": null
}
}
}
So what can be the problem? If you know, please, tell me, I'd really appreciate it!
You're equating query resolvers with field resolvers. Yes, they are both resolvers, but what triggers them is different.
A query resolver is triggered by, you guessed it, a query. Your model defines 2 queries,
getUserandgetBalance.A field resolver resolves a field within a type. Your
Usertype includes thebalancefield but you haven't expressed how to resolvebalancewhen aUserobject is being requested.I believe you'll need to create a model for your
Usertype and include the resolver for thebalancefield there.