In the course Mosh fixes the mistake of typing our param id as a number where it is actually a string because it comes from a url param (api/users/1).
There is still an issue and it causes the same critical error from the DB.
The user can manually type in the link api/users/foo
This causes the same issue because parseInt(‘foo’) will return NaN
I don’t know yet if Mosh comes back to it but here is how I fixed it for now.
// abstracted function to return user | null
const getUserById = async (userId: string) => {
const id = parseInt(userId);
if (isNaN(id)) return null;
return await prisma.user.findUnique({
where: { id },
});
};
export async function GET(
request: NextRequest,
{ params: { userId } }: { params: { userId: string } }
) {
const user = await getUserById(userId);
if (!user)
return NextResponse.json({ error: 'User not found' }, { status: 404 });
return NextResponse.json(user);
}
Sharing my learning experience, you can add methods to the prisma client for specific models or all models
Docs Link Add a Custom Method
So I added this to my client
const prismaClientSingleton = () => {
return new PrismaClient().$extends({
model: {
user: {
async getUserById(userId: string) {
const id = parseInt(userId);
if (isNaN(id)) return null;
return await prisma.user.findUnique({
where: { id },
});
},
},
},
});
};
Need to restart dev server so it will rebuild the client.ts file
Then call it in the api methods like this
const user = await prisma.user.getUserById(userId);
I’m going to update it later to allow for if the param is actually a number type and skip the parseInt part. Then rename it to getById() and have it return entity or null and apply it to all models. That way I have a prisma.model.getById() method which seems to be missing from prisma.
UPDATE : This is all irrelevant now since the lesson on database adapters where we change everything. Now user id is a string.
Extending prisma client is still interesting but as soon as we added the PrismaAdapter(prisma) part I got a type error because PrismaAdapter expects the type of prisma to be
PrismaClient<Prisma.PrismaClientOptions, never, DefaultArgs>
but the type from extending the client the way I did was different so I had to import those types and cast the client as that type. It made TS happy but I don’t know that it would have worked.
Since none of it is needed now, I’ll experiment later with adding methods.