How to Handle N+1 Query Problem in Go GraphQL

Web
Fix the N+1 query problem in Go GraphQL by implementing data loaders to batch database requests into a single query.

The N+1 query problem in Go GraphQL is solved by batching data loaders to execute a single query per type instead of one per field. Implement a DataLoader that collects all requested IDs during the resolve phase and executes one aggregated database query.

type UserLoader struct {
    batchFunc func(ctx context.Context, keys []string) ([]*User, []error)
    cache     map[string]*User
}

func (l *UserLoader) Load(ctx context.Context, id string) (*User, error) {
    if u, ok := l.cache[id]; ok {
        return u, nil
    }
    // Trigger batch if not cached (simplified logic)
    users, errs := l.batchFunc(ctx, []string{id})
    if len(users) > 0 {
        l.cache[id] = users[0]
        return users[0], nil
    }
    return nil, errs[0]
}

func (r *QueryResolver) Users(ctx context.Context) ([]*User, error) {
    // Fetch all users in one query
    allUsers, err := db.FindAllUsers(ctx)
    if err != nil {
        return nil, err
    }
    // Populate loader cache
    loader := &UserLoader{cache: make(map[string]*User)}
    for _, u := range allUsers {
        loader.cache[u.ID] = u
    }
    return allUsers, nil
}