Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to order slice of pointers using gqlgen and dataloaden if some keys are NULL? #49

Open
frederikhors opened this issue Jun 22, 2020 · 1 comment

Comments

@frederikhors
Copy link

frederikhors commented Jun 22, 2020

I have these entities:

  • Golang struct:
type Player struct {
	ID        int
	CreatedAt time.Time
	City      City
	CityID    int
	Team      *Team
	TeamID    *int
	Score     int
}
  • GraphQL schema:
type Player {
  id: ID!
  createdAt: Time!
  City: City!
  Team: Team
  Score: Int!
}

As you can see:

  1. City is mandatory

  2. Team (and TeamID in Golang struct) is NOT mandatory, so I'm using a pointer type (*)

What I don't understand now is how to use dataloaden (a GraphQL dataloader).

Here the generated code for CityById loader, generated with: go run github.com/vektah/dataloaden CityByIdLoader int *my_project/entities.City:

CityById: CityByIdLoader{
  maxBatch: 100,
  wait:     1 * time.Millisecond,
  fetch: func(keys []int) ([]*entities.City, []error) {
    cities, err := myRepo.CitiesByKeys(keys)
    // directly ordered in DB based on keys` order: it works
    return cities, []error{err}
  },
},

What about []*int for TeamID?

Here's the generated code for TeamById loader, generated with: go run github.com/vektah/dataloaden TeamByIdLoader *int *my_project/entities.Team:

TeamById: TeamByIdLoader{
  maxBatch: 100,
  wait:     1 * time.Millisecond,
  fetch: func(keys []int) ([]*entities.Team, []error) {
    teams, err := myRepo.TeamsByKeys(keys)
    // I cannot order in DB because of `NULL` keys, right?
    // How to order these results?
    return teams, []error{err}
  },
},

I don't understand how to re-order teams by keys if I cannot do it in DB because of NULL values in keys.

@MaxInertia
Copy link

MaxInertia commented Jul 17, 2020

@frederikhors If I understand correctly, the simplest solution would be to only use the TeamByIdLoader when Player.teamID is defined.

So your player resolver for the field Team would look like this:

func (r *playerResolver) Team(ctx context.Context, obj *entities.Player) (*entities.Team, error) {
	if obj == nil || obj.TeamID == nil {
		return nil, nil
	}
	return dataloader.For(ctx).TeamById.Load(obj.TeamID)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants