Add Prisma 2 to a NestJS Application
Tags: javascript, node, tutorial
Published: 2020-07-08 02:11:47

# Get Started with NestJS and Prisma

## Tutorial Goal

This tutorial goes through the creation of a basic NestJS application using Prisma 2 (herein simply known as Prisma) as an ORM. This tutorial will use a REST API but it can easily be extended to use GraphQL instead.

This tutorial will not cover NestJS basics nor Prisma basics. It will simply cover how to connect the two technologies.

## Video Tutorial

If you learn better via video, watch my YouTube tutorial:

{% youtube esYVUkFhwik %}

## GitHub Repository

{% github AryanJ-NYC/nestjs-with-prisma-2 %}

## Create a new NestJS Application

```bash
yarn global add @nestjs/cli
nest new nestjs-with-prisma
```

## Add Prisma to NestJS

```bash
yarn add @prisma/client
yarn add @prisma/cli -D
```

```bash
yarn prisma init
```

[`prisma init`](https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-cli/command-reference#init) bootstraps a Prisma project within the current directory. Move `/prisma` to `/src`.

Add Movie model to `/src/prisma/schema.prisma`:

```graphql
model Movie {
  id           Int    @default(autoincrement()) @id
  director     String
  movieName    String
  yearReleased Int
}
```

Create a Prisma migration.

```bash
yarn prisma migrate save --schema src/prisma/schema.prisma --experimental
```

Execute the Prisma migration.

```bash
yarn prisma migrate up --schema src/prisma/schema.prisma --experimental
```

Generate the Prisma Client based on the `Movie` model defined in `src/prisma/schema.prisma`.

```bash
yarn prisma generate --schema src/prisma/schema.prisma
```

## Create Prisma Module + Service

```bash
nest g module prisma
nest g service prisma
```

In `/src/prisma/prisma.service.ts`:

```typescript
import { Injectable } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';

@Injectable()
export class PrismaService extends PrismaClient {}
```

Then export the `PrismaService` from `PrismaModule` (`/src/prisma/prisma.module.ts`):

```typescript
import { Module } from '@nestjs/common';
import { PrismaService } from './prisma.service';

@Module({
  providers: [PrismaService],
  exports: [PrismaService],
})
export class PrismaModule {}
```

## Movies Module + Controller

```bash
nest g module movies
```

```bash
nest g controller movies
```

Import the `PrismaModule` into our `MoviesModule` (in `/src/movies/movies.module.ts`) so we can use `PrismaService`:

```typescript
import { Module } from '@nestjs/common';
import { MoviesController } from './movies.controller';
import { PrismaModule } from 'src/prisma/prisma.module';

@Module({
  imports: [PrismaModule],
  controllers: [MoviesController],
})
export class MoviesModule {}
```

Create a Movie data transfer object (`src/movies/movies.dto.ts`) to represent the movie object:

```typescript
export class MovieDto {
  id: number;
  director: string;
  movieName: string;
  yearReleased: number;
}
```

In `src/movies/movies.controller.ts`:

```typescript
import { Controller, Get, Post, Body } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { MovieDto } from './movie.dto';

@Controller('movies')
export class MoviesController {
  constructor(private readonly prismaService: PrismaService) {}

  @Post()
  create(
    @Body() { director, movieName, yearReleased }: MovieDto,
  ): Promise<MovieDto> {
    return this.prismaService.movie.create({
      data: { director, movieName, yearReleased },
    });
  }

  @Get()
  findAll(): Promise<MovieDto[]> {
    return this.prismaService.movie.findMany();
  }
}
```

## Test Your App

Start your application with:

```bash
yarn start:dev
```

Make HTTP Request to POST http://localhost:3000/movies with a body of:

```json
{
	"director": "George Lucas",
	"movieName": "Star Wars",
	"yearReleased": 1977
}
```

Make HTTP request to GET http://localhost:3000/movies. Your response should be as follows:

```json
[
  {
    "id": 1,
    "director": "George Lucas",
    "movieName": "Star Wars",
    "yearReleased": 1978
  }
]
```

Nice job!