Should we use prisma generated types in frontend code
Using Prisma-generated types directly in your frontend can be convenient, but it comes with some caveats.Here are some points to consider:
When to Use Prisma Types in the Frontend:
-
Simplicity: If your application is relatively simple and you have a strong consistency between the frontend and backend data models, using Prisma types can reduce redundancy and simplify type management.
-
Consistency: Using the same types across both frontend and backend ensures that any changes in the database schema are automatically reflected in the types used in your frontend, reducing the risk of mismatches.
-
Small Projects: For small projects or internal tools, using Prisma types directly can speed up development and reduce the overhead of maintaining separate types.
When to Create Separate Types for the Frontend:
-
Separation of Concerns: The backend and frontend might have different concerns. Backend models often include fields like
password
,createdAt
,updatedAt
, etc., which are not needed or should not be exposed in the frontend. Creating separate types for the frontend allows you to tailor the data structure to your frontend's needs. -
Security: If Prisma types include sensitive information (e.g., passwords, tokens, internal IDs), exposing them directly to the frontend can be risky. By creating separate types, you can ensure only the necessary and safe data is exposed.
-
Different Data Shapes: The frontend might need data in a different shape or with additional computed properties (e.g., formatted dates, combined fields). In such cases, having separate types ensures that the frontend data structure is optimized for UI/UX needs.
-
Large or Growing Projects: As projects grow, maintaining a strict separation between frontend and backend concerns becomes more critical. Separate types allow for more flexibility in evolving the frontend independently from the backend.
Recommended Approach:
-
DTOs (Data Transfer Objects): Create DTOs or interfaces specifically for the data you send to the frontend. This way, you can control exactly what data is exposed, and it allows for future changes in the backend without affecting the frontend.
-
Mapper Functions: Use mapper functions to convert Prisma types to frontend types. This approach gives you flexibility and ensures that the frontend only gets the data it needs.
-
Shared Types: If there are types that are genuinely shared between the frontend and backend (e.g., a simple
User
type without sensitive fields), consider having a shared folder or package where these types live, so both frontend and backend can import them.
Example:
// Backend (Prisma model)
type PrismaUser = {
id: number;
email: string;
password: string;
createdAt: Date;
updatedAt: Date;
};
// Frontend (DTO or Interface)
interface FrontendUser {
id: number;
email: string;
username?: string;
}
// Mapper function
function mapPrismaUserToFrontendUser(prismaUser: PrismaUser): FrontendUser {
return {
id: prismaUser.id,
email: prismaUser.email,
// username can be added or formatted differently
};
}