databaseoptimizationgraphqlfastapistrawberry-graphql

How can I reduce the number of database queries for a one to many association in Strawberry GraphQL and FastAPI?


I'm developing a python GraphQL API server using FastAPI and Strawberry, and I'm implementing this feature: I have two entities, User and Order, which have a one to many association (a User can have many Orders, an Order can only have one User), and I want to get a list of users, each with the list of their orders.

If I were to implement this with a simple REST endpoint, I could make a first query to get the users and then a second query to fetch the orders, sorting out, in the python code, which user each order belongs to based on the foreign key value.

Using Strawberry GraphQL though, it seems I cannot avoid making a query for each user, given that, even using the data loader pattern I would still need to know the order ids beforehand, and this is making the response time much slower.

Is there a solution to this problem? Is my approach completely wrong?


Solution

  • The data loader function itself can do the grouping.

    async def load_orders_by_user(keys: list[int]) -> Iterable[list[Order]]:
        orders = # select * from order where user_id in keys
        groups = {key: [] for key in keys}  # dict maintains order
        for order in orders:
            groups[order.user_id].append(order)
        return groups.values()
    

    Variants on that idea: