Next.js course user can manually type in api/users/foo

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.