Next.js Discord

Discord Forum

Creating a single function for my APIs

Unanswered
Upland Sandpiper posted this in #help-forum
Open in Discord
Upland SandpiperOP
Hello world.

I'm trying to create a function for all my API request. Here are 2 examples with a GET request :

FIRST EXAMPLE :

import { prisma } from "@/config/db";
import { NextResponse } from "next/server";

// GET A SUBMODELE BY ITS ID [subModeleId]
export async function GET(
  _request: Request,
  { params }: { params: { subModeleId: string } }
) {
  const subModeleId = parseInt(params.subModeleId);
  const subModele = await prisma.subModele.findUnique({
    where: {
      id: subModeleId,
    },
  });

  if (!subModele) {
    let error_response = {
      status: "fail",
      message: "No submodele found with the provided ID",
    };
    return new NextResponse(JSON.stringify(error_response), {
      status: 404,
      headers: { "Content-Type": "application/json" },
    });
  }

  let json_response = {
    status: "success",
    data: {
      subModele,
    },
  };
  return new NextResponse(JSON.stringify(json_response), {
    headers: { "Content-Type": "application/json" },
  });
}

31 Replies

Upland SandpiperOP
SECOND EXAMPLE:

export async function GET(
  _request: Request,
  { params }: { params: { marqueId: string } } // /api/marques/[id_marque]/route.ts
) {
  const marqueId = parseInt(params.marqueId);

  const marque = await prisma.marque.findUnique({
    where: {
      id: marqueId,
    },
  });

  if (!marque) {
    let error_response = {
      status: "fail",
      message: "No marque found with the provided ID",
    };
    return new NextResponse(JSON.stringify(error_response), {
      status: 404,
      headers: { "Content-Type": "application/json" },
    });
  }

  let json_response = {
    status: "success",
    data: {
      marque,
    },
  };
  return new NextResponse(JSON.stringify(json_response), {
    headers: { "Content-Type": "application/json" },
  });
}


As you can see, same lines are repeated. I would like a function to gather it. Can you help me, I'm new with Prisma 🙂
Variegated Flycatcher
I can't rewrite the functions right now as i'm away from um laptop.
Part of refactoring would be to rename marqueId/ submoduleId to just 'id': you are already in a given context with only one id: you don't need to complicate the naming.
Then it's about extracting the request and the error message.
Upland SandpiperOP
yes it's about the Prisma request, I don't know how to handle it
and particularly this part :

await prisma.subModele.findUnique
Upland SandpiperOP
please help me 😦
@alfon ? 🙂
Variegated Flycatcher
Either doing so (to be tested as changed out of a context:

export async function GET(
  _request: Request,
  { params }: { params: { id: string } }
) {
  
  return genericGET(
    _request,
    params.id,
    'marque'
  );
}

function genericGET(
  _request: Request,
  id: string,
  model: string
) {

  const data = await prisma[model].findUnique({
    where: {
      id: parseInt(id)
    },
  });

  if (!data) {
    let error_response = {
      status: "fail",
      message: `No ${model} found with the provided ID`,
    };
    return new NextResponse(JSON.stringify(error_response), {
      status: 404,
      headers: { "Content-Type": "application/json" },
    });
  }

  let json_response = {
    status: "success",
    data
  };
  return new NextResponse(JSON.stringify(json_response), {
    headers: { "Content-Type": "application/json" },
  });
}
or by passing the promise as another parameter
Upland SandpiperOP
thank you @Variegated Flycatcher I will give a try
Upland SandpiperOP
genericGET must be a ASYNC function, isn't it ?
here is the error I get on the Prisma request's line :

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'PrismaClient<PrismaClientOptions, never, RejectOnNotFound | RejectPerOperation | undefined>'.
No index signature with a parameter of type 'string' was found on type 'PrismaClient<PrismaClientOptions, never, RejectOnNotFound | RejectPerOperation | undefined>'.
@Upland Sandpiper SECOND EXAMPLE: javascript export async function GET( _request: Request, { params }: { params: { marqueId: string } } // /api/marques/[id_marque]/route.ts ) { const marqueId = parseInt(params.marqueId); const marque = await prisma.marque.findUnique({ where: { id: marqueId, }, }); if (!marque) { let error_response = { status: "fail", message: "No marque found with the provided ID", }; return new NextResponse(JSON.stringify(error_response), { status: 404, headers: { "Content-Type": "application/json" }, }); } let json_response = { status: "success", data: { marque, }, }; return new NextResponse(JSON.stringify(json_response), { headers: { "Content-Type": "application/json" }, }); } As you can see, same lines are repeated. I would like a function to gather it. Can you help me, I'm new with Prisma 🙂
import { prisma } from "@/config/db";
import { NextResponse } from "next/server";

async function getResponse(entityType: string, entityId: number) {
  let response;

  if (entityType === "subModele") {
    const subModele = await prisma.subModele.findUnique({
      where: {
        id: entityId,
      },
    });

    if (!subModele) {
      response = {
        status: "fail",
        message: "No submodele found with the provided ID",
      };
      return new NextResponse(JSON.stringify(response), {
        status: 404,
        headers: { "Content-Type": "application/json" },
      });
    }

    response = {
      status: "success",
      data: {
        subModele,
      },
    };
  } else if (entityType === "marque") {
    const marque = await prisma.marque.findUnique({
      where: {
        id: entityId,
      },
    });

    if (!marque) {
      response = {
        status: "fail",
        message: "No marque found with the provided ID",
      };
      return new NextResponse(JSON.stringify(response), {
        status: 404,
        headers: { "Content-Type": "application/json" },
      });
    }

    response = {
      status: "success",
      data: {
        marque,
      },
    };
  }

  return new NextResponse(JSON.stringify(response), {
    headers: { "Content-Type": "application/json" },
  });
}

export async function GET(
  _request: Request,
  { params }: { params: { entityType: string; entityId: string } }
) {
  const entityId = parseInt(params.entityId);

  return getResponse(params.entityType, entityId);
}
haven't tested though, but give it a shot, worth nothing anyways 🤷‍♂️
Upland SandpiperOP
well thank you but the model is hardcoded
this part :

if (entityType === "marque") {
const marque = await prisma.marque.findUnique({
where: {
id: entityId,
},
});
same here :

if (entityType === "subModele") {
const subModele = await prisma.subModele.findUnique({
where: {
id: entityId,
},
});
what don't you understand?
Upland SandpiperOP
I understand.
what else if I have 10 000 entityType ?
oh, wym hardcoded then?
Upland SandpiperOP
the function should handle many entities as possible
that's why you put it as a param : entityType
if you harcoded them, I don' t need a function
the goal of a function is to avoid repetition
I need something like this :

const res = await prisma.myTable.findUnique()

myTable would be a parameter's function
have you tried using objects dynamically?
Upland SandpiperOP
what do you mean by that
@Upland Sandpiper genericGET must be a ASYNC function, isn't it ?
Variegated Flycatcher
yes indeed, for the Prisma error, then pass the query as a parameter to 'genericGet'
Upland SandpiperOP
can you show me please ?
Variegated Flycatcher
At this point, I think it would be better that you are ever giving it a try or explaining what you don't understand.
It's not a Prisma or a NextJS issue but a JavaScript one about how to refactor functions.

Rather than providing you the answer directly, it'll be way more benefic for you to experiment.