Getting Started with NestJS and Prisma: A Step-by-Step Tutorial

Getting Started with NestJS and Prisma: A Step-by-Step Tutorial
Getting Started with NestJS and Prisma: A Step-by-Step Tutorial


NestJS is a cutting-edge Node.js framework designed to help developers build efficient, modular, and scalable server-side applications. Prisma, on the other hand, is a next-generation ORM (Object-Relational Mapping) tool for Node.js and TypeScript, designed to streamline database access. Together, they create a robust environment for building modern, data-driven applications.

In this guide, you will learn how to integrate Prisma with NestJS and use them to build a fully functional API.

Prerequisites

Before starting, ensure you have the following:

  • Node.js (version 16 or later) installed.
  • A basic understanding of TypeScript and NestJS.
  • A database (e.g., PostgreSQL, MySQL, or SQLite).
  • Installed npm or yarn as the package manager.

Setting Up the Project

  • Create a New NestJS Project
Initialize a NestJS Project using the CLI:

npx @nestjs/cli new nestjs-prisma-tutorial
cd nestjs-prisma-tutorial

  • Install Prisma
Add Prisma and its TypeScript client:

npm install prisma @prisma/client

  • Initialize Prisma
Initialize Prisma in your project:

npx prisma init


When you initialize Prisma, it generates a prisma directory containing a schema.prisma file. This is where you’ll define your database models and relationships.

  • Set Up Database
Open the .env file in your project and add the DATABASE_URL with the connection string for your database. For example, for PostgreSQL:

DATABASE_URL="postgresql://user:password@localhost:5432/nestjs_prisma"


Defining the Prisma Schema

  • In the schema.prisma file, define a User model to represent a user entity in your application. For instance:

generator client {
provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model User { id Int @id @default(autoincrement()) email String @unique name String createdAt DateTime @default(now()) }

  • To create the database structure based on your schema, execute the following command:

npx prisma migrate dev --name init

  • Generate the Prisma client:

npx prisma generate


Integrating Prisma with NestJS

  • Install Prisma Service Dependencies
Install additional Prisma-related dependencies:

npm install @nestjs/prisma

  • Create a Prisma Module
Generate a Prisma module to manage database interactions:

nest g module prisma

  • Create a Prisma Service
Generate a Prisma service:

nest g service prisma


In the prisma.service.ts file, initialize the Prisma client to handle database interactions:

import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from '@prisma/client'; @Injectable() export class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy { async onModuleInit() { await this.$connect(); } async onModuleDestroy() { await this.$disconnect(); } }

  • Export PrismaService
In the prisma.module.ts file, export the PrismaService:

import { Global, Module } from '@nestjs/common';
import { PrismaService } from './prisma.service'; @Global() @Module({ providers: [PrismaService], exports: [PrismaService], }) export class PrismaModule {}


Creating a User Module

  • Generate User Module

nest g module user
nest g service user nest g controller user

  • Implement User Service
In user.service.ts, inject the PrismaService and create methods for CRUD operations:

import { Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service'; @Injectable() export class UserService { constructor(private prisma: PrismaService) {} async getAllUsers() { return this.prisma.user.findMany(); } async getUserById(id: number) { return this.prisma.user.findUnique({ where: { id } }); } async createUser(data: { email: string; name: string }) { return this.prisma.user.create({ data }); } async updateUser(id: number, data: { name?: string; email?: string }) { return this.prisma.user.update({ where: { id }, data }); } async deleteUser(id: number) { return this.prisma.user.delete({ where: { id } }); } }

  • Implement User Controller
In user.controller.ts, define REST endpoints:

import { Controller, Get, Param, Post, Body, Put, Delete } from '@nestjs/common';
import { UserService } from './user.service'; @Controller('users') export class UserController { constructor(private userService: UserService) {} @Get() getAllUsers() { return this.userService.getAllUsers(); } @Get(':id') getUserById(@Param('id') id: number) { return this.userService.getUserById(+id); } @Post() createUser(@Body() data: { email: string; name: string }) { return this.userService.createUser(data); } @Put(':id') updateUser(@Param('id') id: number, @Body() data: { name?: string; email?: string }) { return this.userService.updateUser(+id, data); } @Delete(':id') deleteUser(@Param('id') id: number) { return this.userService.deleteUser(+id); } }


Testing the API

  • Start the NestJS server:

npm run start:dev

To test the API endpoints use tools such as Postman or Curl. For example:
  • GET all users: GET http://localhost:3000/users
  • Create a user:

    POST http://localhost:3000/users
    { "email": "test@example.com", "name": "Test User" }


This guide walked you through how to integrate NestJS with Prisma to build a robust and scalable API. By leveraging Prisma's simplicity and NestJS's modularity, you can develop data-driven applications with ease.

For further improvements, consider adding middleware for input validation, error handling, and authentication to make your application production-ready.

Post a Comment

Previous Post Next Post