about_us_bg

Blog

How to create simple API using Next.js

Under this topic, we are going to learn about how to create our own simple API using Next.js API Routes, Prisma and MongoDB

First, we should create our application with Next.js + TS

npx create-next-app@latest

So, After we should create our API with Prisma ORM

npm i prisma --save-dev

Initialize the prisma to this application

npx prisma init

Configure the prisma settings

✔ Your Prisma schema was created at prisma/schema.prisma You can now open it in your favorite editor.

warn You already have a .gitignore file. Don't forget to add `.env` in it to not commit any private information.

Next steps:

1. Set the DATABASE_URL in the .env file to point to your existing database. If your database has no tables yet, read https://pris.ly/d/getting-started

2. Set the provider of the datasource block in schema.prisma to match your database: postgresql, mysql, sqlite, sqlserver, mongodb or cockroachdb.

3. Run prisma db pull to turn your database schema into a Prisma schema.

4. Run prisma generate to generate the Prisma Client. You can then start querying your database.

And Create your MongoDB Database using Compass or Website. connect with your Prisma on .env DATABASE_URL and as last, create your modal and generate the Schema using Prisma

model Post{
id String @id @default(auto()) @map("_id") @db.ObjectId
title String
description String
date DateTime @default(now())
}

Now you are ready to generate your schema,

npx prisma generate

And we need to push (synchronize) our schema with database, there’s a Prisma command to do it !

npx prisma db push

And we need to push (synchronize) our schema with database, there’s a Prisma command to do it !

After the synchronization, we should define our Client to send queries to database and get communication with database.
To create our custom Client, we should install a package named @prisma/client

npm i @prisma/client

So after that, we ll use a template to define the PrismaClient that you can also find on [prisma.io](http://prisma.io) , It will stop the problems about pre-defined prisma clients to not occur a problem in the future, while we re developing we ll use just one client and it will be the one which we ve defined.
This should be defined inside /prisma/index.ts

            import { PrismaClient } from "@prisma/client";

            let prisma: PrismaClient;
            declare global {
              namespace NodeJS {
                interface Global {
                  prisma: PrismaClient;
                }
              }
            }

            if (process.env.NODE_ENV === "production") {
              prisma = new PrismaClient();
            } else {
              if (!global.prisma) {
                global.prisma = new PrismaClient();
              }
              prisma = global.prisma;
            }

            export default prisma;
            

So, after that we’re completely ready to create our Next API in the project ! 🎉
So, to create a API in Next.js, it’s easy. Just create a folder named **/api** inside the **/app** folder, and start to create your API folders depends on the page, for example if we have [www.localhost.com/blog](http://www.localhost.com/blog) page, you should create a path like **/api/blog/route.ts** and you can define the API Settings in it.
For dynamic routes, for example [www.localhost.com/blog/1](http://www.localhost.com/blog/1) you should create a separated API and its path should be like : **/api/blog/[id]/route.ts .** in Next.js we’re defining the dynamic routes path with square brackets "[]”. Let’s do it with another example like **[www.localhost.com/movies/1](http://www.localhost.com/movies/1)** so it should defined like **/api/movies/[id]/route.ts .**
And next thing what I want to emphasize is, how to define request types in Next API ?
so, basically we’re defining them with pre-defined function names. For example let’s take a look at the code that we wrote :

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

                        async function main() {
                            try {
                            await prisma.$connect();
                            } catch (error) {
                            return Error("Database Connection Unsuccessful");
                            }
                        }

                        export const GET = async (req: Request, res: NextResponse) => {
                            try {
                                console.log("Get");
                                await main();
                                const posts = await prisma.post.findMany();
                                return NextResponse.json({ message: "Success", posts }, { status: 200 });
                            } catch (error) {
                                return NextResponse.json({ message: "Error", error }, { status: 500 });
                            }
                        };
                        

Let’s describe this code snippet with list and one by one :
1. Firstly, I want to start with describing the function structure for the GET Request, as you’ve seen from the example, we’ve created a ASYNC function that named as GET and as parameters, we gave req type of Request and res type of NextResponse. So whenever we request to server to get /blog page, this function will be executed.
2. As you ve seen we’ve defined the connection from prisma with main() function, so whenever we call main() it will execute the connection with prisma and db.
3. With defining posts with prisma.post.findMany(), we’ll get all the post objects inside the post schema. (by the way, prisma has its own IntelliSense, while writing prisma and “.” it will show and describe everything about the built-in functions and the schema shortcuts inside IDE, would be good to inspect and take a look at this if you’re new in prisma.)
So after this process, you can go and check the API’s status from Postman or Browser with send a GET request to yourlocalhost:yourport/api/blog
If everything gone well from here and we could get the good response from API, we can add the finally condition to disconnect with database because we’re completed our job with database.

                            export const GET = async (req: Request, res: NextResponse) => {
                              try {
                                console.log("Get");
		                            //we re connecting to database to do our job
                                await main();
                                const posts = await prisma.post.findMany();
                                return NextResponse.json({ message: "Success", posts }, { status: 200 });
                              } catch (error) {
                                return NextResponse.json({ message: "Error", error }, { status: 500 });
                              } finally {
		                            // we re completed the job and disconnecting from Database
                                await prisma.$disconnect();
                              }
                            };
                        

Let’s Create our POST Request with same way !

                            export const POST = async (req: Request, res: NextResponse) => {
                              try {
                                const { title, description } = await req.json();
                                await main();
                                const post = await prisma.post.create({ data: { title, description } });
                                return NextResponse.json({ message: "Success", post }, { status: 201 });
                              } catch (error) {
                                return NextResponse.json({ message: "Error", error }, { status: 500 });
                              } finally {
                                await prisma.$disconnect();
                              }
                            };
                        

1. Firstly, we are getting the data from the request body with await keyword because we don’t know when we will get the req, and with req.json() function we’re getting the request body.
2. With await main() we re connected with db
3. We will create the post with the req body informations in database using .create() method from prisma, firstly connected the collection using [prisma.post](http://prisma.post) and after that we’re executing the create() function with object parameter as you can see. This object parameter takes “data” property to hold the data and insert into database.
4. The other processes are same with GET request function
Let’s create a GET request for the dynamic route also :

                        export const GET = async (req: Request, res: NextResponse) => {
                          try {
                            console.log("You're GET requested to a dynamic route !");
                            const id = req.url.split("/blog/")[1];
                            // console.log(id);
                            await main();
                            const post = await prisma.post.findFirst({ where: { id } });
                            if (!post) {
                              return NextResponse.json({ message: "Not Found" }, { status: 404 });
                            } else {
                              return NextResponse.json({ message: "Success", post }, { status: 200 });
                            }
                          } catch (error) {
                            return NextResponse.json({ message: "Error", error }, { status: 505 });
                          } finally {
                            await prisma.$disconnect();
                          }
                        };
                    

Same things, we’ve just used .findFirst() method to find the matching id with our posts. We are using where:{} to query in DB, in this case we’ve search for the id which we passed through URL, like [www.localhost.com/blog/213](http://www.localhost.com/blog/213) so the id will be 213 and we will take a search on database for post which has this id.
And after that We need to configurate 2 more requests. Which are PUT and DELETE. Let’s continue with PUT (UPDATE):

                            export const PUT = async (req: Request, res: NextResponse) => {
                              try {
                                console.log("You're PUT requested to a dynamic route !");
                                const id = req.url.split("/blog/")[1];
                                const { title, description } = await req.json();
                                await main();
                                const post = await prisma.post.update({
                                  where: { id },
                                  data: { title, description },
                                });
                                return NextResponse.json({ message: "Success", post });
                              } catch (error) {
                                return NextResponse.json({ message: "Error", error }, { status: 505 });
                              } finally {
                                await prisma.$disconnect();
                              }
                            };
                        

In the UPDATE Case, we took the values from request body which are title and description, and using .update() built-in method from prisma we’ve updated the post, where property to detect the post which should be updated, and data property to update its values.
In DELETE Case:

                            export const DELETE = async (req: Request, res: NextResponse) => {
                                  try {
                                    console.log("You're DELETE requested to a dynamic route !");
                                    const id = req.url.split("/blog/")[1];
                                    await main();
                                    await prisma.post.delete({ where: { id } });
                                    const posts = await prisma.post.findMany();
                                    return NextResponse.json({ message: "Successfully Deleted", posts });
                                  } catch (error) {
                                    return NextResponse.json({ message: "Error", error }, { status: 505 });
                                  } finally {
                                    await prisma.$disconnect();
                                  }
                             };
                        

We’ve just given the id of the post which should be deleted, and .delete() method does the job. With .findMany() we just showed that the list of posts and Dev. will understand that the post is deleted.
And with these configurations, we’re done with the Backend part 🎉 If any question? You can reach us :)

Categories

  • category_img
    Development
  • category_img
    Apps
  • category_img
    Identity
  • category_img
    SEO&SMM
  • category_img
    UI/UX Design

Tags

Portfolio
Business
Web
Corporate
Creative
Application
Development
Interface