RSS Amplifier

Andraž Bajt's blog · May 6, 2023

GraphQL ❤️ SQLite

0
Sign in to vote or save

This page cannot be shown here. You can still read it on the original site — the toolbar below keeps your place in the directory.

If you’ve done anything nontrivial with GraphQL you’re probably familiar with how “N+1 select problem” sneaks up on you. If not, this is how gqlgen docs explain it: Imagine your graph has query that lists todos… 1 query { todos { user { name } } } and the todo.user resolver reads the User from a database… 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 func ( r * todoResolver )…

If you’ve done anything nontrivial with GraphQL you’re probably familiar with how “N+1 select problem” sneaks up on you. If not, this is how gqlgen docs explain it:

Imagine your graph has query that lists todos…

1
query { todos { user { name } } }

and the todo.user resolver reads the User from a database…

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
func (r *todoResolver) User(ctx context.Context, obj *model.Todo) (*model.User, error) {
	res := db.LogAndQuery(
		r.Conn,
		"SELECT id, name FROM users WHERE id = ?",
		obj.UserID,
	)
	defer res.Close()

	if !res.Next() {
		return nil, nil
	}
	var user model.User
	if err := res.Scan(&user.ID, &user.Name); err != nil {
		panic(err)
	}
	return &user, nil
}

The query executor will call the Query.Todos resolver which does a select * from todo and returns N todos. If the nested User is selected, the above UserRaw resolver will run a separate query for each user, resulting in N+1 database queries. e.g.

Read on /blog/2023-05-06-graphql-sqlite/

Comments

Nothing yet. Say the first thing.

    Sign in to join the conversation.