DEV Community

Cover image for Next.js application for Beginners: Simple API with Prisma.
Ayas Hussein
Ayas Hussein

Posted on

Next.js application for Beginners: Simple API with Prisma.

We are going to create a Next.js application that uses both client-side and server-side rendering with authentication and data fetching. We'll implement the following features:

  • Authentication: A simple login flow using a mock API.
  • Data Fetching: Display user-specific data fetched from a backend.
  1. Add a Database
    we'll use SQLite with Prisma (an ORM).

  2. Install Prisma:

npm install prisma --save-dev
npm install @prisma/client

Enter fullscreen mode Exit fullscreen mode

Initialize Prisma:

npx prisma init

Enter fullscreen mode Exit fullscreen mode
  1. Update the prisma/schema.prisma file to define a User model:
datasource db {
  provider = "sqlite"
  url      = "file:./dev.db"
}

generator client {
  provider = "prisma-client-js"
}

model User {
  id       Int      @id @default(autoincrement())
  email    String   @unique
  password String
}

Enter fullscreen mode Exit fullscreen mode
  1. Migrate the database:
npx prisma migrate dev --name init

Enter fullscreen mode Exit fullscreen mode
  1. npx prisma migrate dev --name init
npx prisma migrate dev --name init
npx prisma db seed

Enter fullscreen mode Exit fullscreen mode

Next, we will add Login API (pages/api/auth/login.js):

import bcrypt from 'bcryptjs';
import jwt from 'jsonwebtoken';
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

export default async function handler(req, res) {
  if (req.method !== 'POST') {
    return res.status(405).json({ message: 'Method not allowed' });
  }

  const { email, password } = req.body;

  try {
    const user = await prisma.user.findUnique({ where: { email } });

    if (!user || !bcrypt.compareSync(password, user.password)) {
      return res.status(401).json({ message: 'Invalid credentials' });
    }

    const token = jwt.sign({ email: user.email, id: user.id }, process.env.JWT_SECRET, { expiresIn: '1h' });

    res.status(200).json({ token });
  } catch (error) {
    res.status(500).json({ message: 'Internal server error' });
  }
}

Enter fullscreen mode Exit fullscreen mode

Create User API (pages/api/auth/register.js): Add an API route to register new users.

import bcrypt from 'bcryptjs';
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

export default async function handler(req, res) {
  if (req.method !== 'POST') {
    return res.status(405).json({ message: 'Method not allowed' });
  }

  const { email, password } = req.body;

  try {
    const hashedPassword = bcrypt.hashSync(password, 10);

    const newUser = await prisma.user.create({
      data: { email, password: hashedPassword },
    });

    res.status(201).json({ message: 'User created', user: newUser });
  } catch (error) {
    res.status(500).json({ message: 'Internal server error' });
  }
}

Enter fullscreen mode Exit fullscreen mode

Update Data Fetching API
Modify the pages/api/user.js route to fetch user data from the database.

import jwt from 'jsonwebtoken';
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

export default async function handler(req, res) {
  const { authorization } = req.headers;

  if (!authorization) {
    return res.status(401).json({ message: 'Unauthorized' });
  }

  try {
    const token = authorization.split(' ')[1];
    const decoded = jwt.verify(token, process.env.JWT_SECRET);

    const user = await prisma.user.findUnique({ where: { id: decoded.id } });

    if (!user) {
      return res.status(404).json({ message: 'User not found' });
    }

    res.status(200).json({ email: user.email, message: 'Welcome to your dashboard!' });
  } catch (error) {
    res.status(401).json({ message: 'Invalid token' });
  }
}

Enter fullscreen mode Exit fullscreen mode

Environment Setup
In .env.local, configure the database connection:

DATABASE_URL="file:./dev.db"
JWT_SECRET="your-secret-key"

Enter fullscreen mode Exit fullscreen mode

Test the Application

npm run dev

Enter fullscreen mode Exit fullscreen mode

After the application gets started:
Use Postman or the frontend to:

  • Register a new user: Use the /api/auth/register endpoint.
  • Log in: Use the /api/auth/login endpoint.
  • Fetch user data: Use the /api/user endpoint with a valid token.

Top comments (0)