Support/help with promise-based resolvers
See original GitHub issueI think I have a good use-case for non-async, promise-based resolution.
We are making django ORM from our dataloaders. We moved away from using async in django 3.0 because django would force us to isolate ORM calls and wrap them in sync_to_async. Instead, we ditched async and used promises with a generator based syntax. Examples below:
What we’d like to do, but django doesn’t allow
class MyDataLoader(...):
async def batch_load(self, ids):
data_from_other_loader = await other_loader.load_many(ids)
data_from_orm = MyModel.objects.filter(id__in=ids) # error! can't call django ORM from async context.
# return processed combination of orm/loader data
What django would like us to do
class MyDataLoader(...):
async def batch_load(self, ids):
data_from_other_loader = await other_loader.load_many(ids)
data_from_orm = await get_orm_data()
# return processed combination of orm/loader data
@sync_to_async
def get_orm_data(ids):
return MyModel.objects.filter(id__in=ids)
What we settled on instead (ditch async, use generator-syntax around promises)
class MyDataLoader(...):
def batch_load(self,ids):
data_from_other_loader = yield other_loader.load_many(ids)
data_from_orm = MyModel.objects.filter(id__in=ids)
# return processed combination of orm/loader data
I have a generator_function_to_promise tool that allows this syntax, as well as a middleware that converts generators returned from resolvers into promises. I have hundreds of dataloaders following this pattern. I don’t want to be stuck isolating all the ORM calls as per django’s recommendations because it’s noisy and decreases legibility.
If it’s not difficult to re-add promise support, I’d really appreciate it. If not, can anyone think of a solution to my problem?
Issue Analytics
- State:
- Created 2 years ago
- Comments:13 (7 by maintainers)

Top Related StackOverflow Question
Something like this will eventually be integrated in GraphQL-Core, see discussion #155. Promises however will not be supported in GraphQL-Core 3 because they are not part of standard Python and because the only existing library for these is not maintained any more.
@AlexCLeduc @jkimbo Thanks for your feedback. I understand that deferred execution (particularly for the DataLoader mechanism) without asyncio is a real world use case that we should support in some way.
@jkimbo you have a point that adding this support in a separate package or on a higher level like Graphene or Strawberry has also its downsides. If it relies on internal details of GraphQL-core it would be prone to break with every new release of GraphQL-core. To avoid this, we could either extend the official API (as suggested above) or actually move such support into GraphQL-core itself.
If we do this, then I think we agree it should be done in a generic way, not special casing for the old Promise lib or Django, and it should not degrade performance for the existing execution modes. Currently I don’t have the time and need to work on this myself, so the initiative must come from people like you. Don’t hesitate to send in PRs with suggestions. But please always include tests and performance benchmarks (see the tests/benchmarks directory).
I will keep this issue open for discussion and coordination of these efforts.