ChilliCream / graphql-platform

Welcome to the home of the Hot Chocolate GraphQL server for .NET, the Strawberry Shake GraphQL client for .NET and Banana Cake Pop the awesome Monaco based GraphQL IDE.
https://chillicream.com
MIT License
5.25k stars 744 forks source link

Data loader with complex filtering #356

Closed featherbits closed 4 years ago

featherbits commented 5 years ago

I would like to add more filtering/fetching parameters to data loader that are other than ID/key of object that I'm fetching. What would be the preferred way on doing that?

From samples, it seems, that I should beforehand retrieve required IDs and then pass them to data loader in order to retrieve objects that are linked to those IDs.

I have a hunch that this https://hotchocolate.io/docs/next/dataloaders#custom-data-loaders must be used because GreenDonut cannot handle my case? However, not sure how custom data loaders must be implemented.

As a hack, I though I could specify a custom object as key while using GreenDonut, so that I can pass filtering arguments to data loader, but not sure how legitimate of a solution that is.

michaelstaib commented 5 years ago

From samples, it seems, that I should beforehand retrieve required IDs and then pass them to data loader in order to retrieve objects that are linked to those IDs.

Exactly, that's basically how the DataLoader pattern is defined by facebook.

But if you could explain your case in more detail and if it is a common case we could include it into GreenDonut.

Can you explain your problem in more detail?

featherbits commented 5 years ago

The idea is really simple. I would like to fetch my objects by more than one parameter which is not an object primary key directly. One example would be to retrieve company object that user belongs to. So, I should retrieve company by user's id. Then, what if I would like to add more filters on in? It would probably look like this

{
  a: myCompany(Role: "programmer") {
    name
  }

  b: myCompany(Role: "magician") {
    name
  }
}

With current limitations one would require to query storage to find my company ID by given role and then pass that company ID to data loader. This would result into three queries being made.

It should be possible to retrieve both of these company objects in one query by filtering database by user's id and role in company. I think the only question is what would be the best approach form APIs perspective to identify each request in batch. Have not really looked into detail how that is handled currently.

michaelstaib commented 5 years ago

I forwarded this to @rstaib.

michaelstaib commented 5 years ago

@rstaib I think this is the case @featherbits would like to have

Loading by alternative keys. Occasionally, some kind of value can be accessed in multiple ways. For example, perhaps a "User" type can be loaded not only by an "id" but also by a "username" value. If the same user is loaded by both keys, then it may be useful to fill both caches when a user is loaded from either source....

@featherbits correct me when I am wrong.

giangcoi48k commented 4 years ago

Hi. I'm practicing with graphql using hotchocolate. I also using MediatR and resolved complex filtering data loader. Please take a look my demo project: https://github.com/giangcoi48k/MediatR-Graphql

michaelstaib commented 4 years ago

With version 11 we now have a more abstract way of batching data fetches. So while we keep the DataLoader close. to the spec, we allow for more complex systems to be implemented on the new IBatchDispatcher API.