I am using prisma client in my graphql server.
Following best practices, I made the resolver layer just a thin layer that delegates the actual fetching of data to a data access layer. The data access layer also does things like authorization and request level caching using dataloader.
I can't find a good way to fetch relations of entities in this setup because prisma client uses chaining of function calls on the promise object for fetching relations, but since my resolver doesn't call prisma client directly, it doesn't have access to the prisma client promise and so cannot call the chained relationship functions.
See the following example:
Sample data model:
type Apartment {
id: ID!
floor: Int
building: Building @pgRelation(column: "building_id")
}
type Building {
id: ID!
buildingNumber: Int
}
Sample resolver for apartment:
module.exports = {
Query: {
apartment: async (parent, { where }, { apartmentDAO }) => {
return apartmentDAO.apartment(where);
}
},
Apartment: {
building: async (parent, args, { buildingDAO }) => {
return buildingDAO.buildingByApartmentId(parent.id);
}
}
};
Sample implementation of buildingByApartmentId
in the data access layer:
buildingByApartmentId: (apartmentId) => {
// Some authorization logic goes here
// Some other common data access logic goes here
// ....
return prismaClient.apartment({ id: apartmentId }).building();
}
This is not a good implementation for a few reasons:
- I already fetched the apartment at it exists in the cache but I cannot reuse that because I have to fetch apartment again just to get to the building.
- For every relation in apartment I will need to implement a special function like this to fetch that specific relation by apartemntId. This is wasteful and misses the point of prisma implementing most of the queries for me.
Is there a better way to implement this that I am missing?
I know prisma binding would solve this issue but:
- Prisma client seems like the more up to date way of using primsa.
- For authorization purposes, prisma client is much more powerful.