Hey @igolka97 👋, great question.
While Prisma is unlike traditional ORMs in many ways, it is still possible to wrap it in a thin layer of abstraction if that is something you want for your architecture. Most of the time, wrapping Prisma looks like writing wrapper functions around Prisma queries instead of the usual class-based pattern.
This is a reasonably common question, so here are a few links to previous discussions and questions around this topic:
- #3929
- Slack conversation about repository pattern
- #5273
I would be happy to address any more specific questions you have!
I'm learning Nest and Prisma and I saw some public repositories where the devs only interact with the Prisma service in the Repository file.
Why is a bad practice to interact with Prisma service in the Service file instead of Repository? Why we actually have a Repository?
Is a repository pattern with generics possible?
prisma2 - How can I create a custom repository in Prisma 2 using NestJS like TypeORM? - Stack Overflow
Question about Prisma and DI
Yes, but if you think about changing databases in the future, you have to put another layer of abstraction with repository pattern, in that way, the origin of data can be prisma, firebase, or any other source that you want.
More on reddit.comtypescript - Is the Repository Pattern needed with Prisma if you have a service layer? - Stack Overflow
I am using prisma for a user data base, and I was following this guide: https://docs.nestjs.com/recipes/prisma
However, I had a question about this code specifically:
@Injectable()
export class UserService {
constructor(private prisma: PrismaService) {}
...
So the UserService takes in a PrismaService object.
But my question is, what if I decide to use some other database in the future, such as Firebase or MongoDB. Won't I have to change the code in UserService because it depends on PrismaService itself? Is there another way to do this?
Yes, but if you think about changing databases in the future, you have to put another layer of abstraction with repository pattern, in that way, the origin of data can be prisma, firebase, or any other source that you want.
You could encapsulate your data layer in another abstraction and inject that instead. For example, you could create a dataService or databaseService and inject that. If you need to change between prisma to other things you can just change the implementation. As long as it adheres to the databaseService interface, it's all good. (This type of pattern is usually called the repository pattern)
What is the preferred way to use Entities in the NestJS framework with Prisma?
The command `nest g resource ResourceName`, creates the Controller, Module, Service, and Entity. All the Prisma tutorials and NestJS/Prisma examples show the Service calling directly into the Prisma client. My application is using Prisma to define the tables and run the migrations.
Should I just delete the entities created from the `nest g resource` command?
I don't have a problem with the pattern of going directly to the Prisma Client from the Service, but is this the idiomatic way of doing things in NestJS/Prisma?
Thank you!
For context, I am building a few reference implementations using Prisma, MikroORM, Drizzle, and TypeORM to evaluate which one will work best with my team for a new project.
Update: I decided to skip building entities from the Prisma object returned from Prisma Service. The controller will return a model object and not the entity. Seems like a lot of overhead to convert to an entity, just to convert it to a model. I’m also skipping the Repository pattern. If I ever refactor Prisma to something else, it is the same amount of code to change.