Engineering

⌘K
  1. Home
  2. Docs
  3. Engineering
  4. NestJS
  5. NestJS with Nx, Prisma ORM, MariaDB Database, and GraphQL API

NestJS with Nx, Prisma ORM, MariaDB Database, and GraphQL API

Initialize NestJS Shared Library for “model” with Prisma Support

Reference:

yarn add --dev prisma

nx g @nrwl/nest:library model
cd libs/model
../../node_modules/.bin/prisma init

Edit workspace.json and add the following targets into “model” project:

        "prisma-generate": {
          "executor": "@nrwl/workspace:run-commands",
          "outputs": [],
          "options": {
            "command": "../../node_modules/.bin/prisma generate",
            "cwd": "libs/model"
          }
        },
        "migrate-save": {
          "executor": "@nrwl/workspace:run-commands",
          "outputs": [],
          "options": {
            "command": "../../node_modules/.bin/prisma migrate dev --create-only --preview-feature --schema ./prisma/schema.prisma",
            "cwd": "libs/model"
          }
        },
        "migrate-up": {
          "executor": "@nrwl/workspace:run-commands",
          "outputs": [],
          "options": {
            "command": "../../node_modules/.bin/prisma migrate dev --preview-feature --schema ./prisma/schema.prisma",
            "cwd": "libs/model"
          }
        },
        "migrate-reset": {
          "executor": "@nrwl/workspace:run-commands",
          "outputs": [],
          "options": {
            "command": "../../node_modules/.bin/prisma migrate reset --preview-feature --schema ./prisma/schema.prisma",
            "cwd": "libs/model"
          }
        },
        "migrate-deploy": {
          "executor": "@nrwl/workspace:run-commands",
          "outputs": [],
          "options": {
            "command": "../../node_modules/.bin/prisma migrate deploy --preview-feature --schema ./prisma/schema.prisma",
            "cwd": "libs/model"
          }
        },
        "migrate-status": {
          "executor": "@nrwl/workspace:run-commands",
          "outputs": [],
          "options": {
            "command": "../../node_modules/.bin/prisma migrate status --preview-feature --schema ./prisma/schema.prisma",
            "cwd": "libs/model"
          }
        },
        "studio": {
          "executor": "@nrwl/workspace:run-commands",
          "outputs": [],
          "options": {
            "command": "../../node_modules/.bin/prisma studio --schema ./prisma/schema.prisma",
            "cwd": "libs/model"
          }
        }

schema.prisma File

Before you edit, it’s a good idea to install Prisma extension for VS Code.

// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

datasource db {
  provider = "mysql"
  url      = env("DATABASE_URL")
}

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

model Nonprofit {
  id Int @id @default(autoincrement())
  createdAt DateTime @default(now())
  email String @unique
  name String?
}

Create src/libs/

After editing, you can run migration by:

nx run model:migrate-up

Prisma Service in NestJS

Generate the PrismaService:

nx generate @nrwl/nest:service --name=prisma --project=model --directory=lib

Code for libs/model/src/lib/prisma/prisma.service.ts:

import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';

/**
 * https://docs.nestjs.com/recipes/prisma
 */
@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy {
  async onModuleInit() {
    await this.$connect();
  }

  async onModuleDestroy() {
    await this.$disconnect();
  }
}

Generate NestJS Resource with GraphQL Code First

yarn add @nestjs/graphql graphql-tools graphql apollo-server-express

In file app/app.module.ts, add the following inside “imports“:

    GraphQLModule.forRoot({
      installSubscriptionHandlers: false,
      // See: https://stackoverflow.com/a/61048144/122441
      autoSchemaFile: process.env.NODE_ENV === 'development' ? 'apps/fund/schema.gql' : true,
    }),

Now you can generate a skeleton resource: (Important: Make sure the name is plural, as it needs that to differentiate between collection and single document queries)

nx generate @nestjs/schematics:resource --name=Nonprofits --sourceRoot=apps/fund/src --type=graphql-code-first

Edit src/app/nonprofits/nonprofits.service.ts, first you must inject PrismaService:

  constructor(private prismaService: PrismaService) {
  }

After that you can use the Prisma client, for example:

import { Nonprofit } from './entities/nonprofit.entity';

// ...

  async findAll(): Promise<Nonprofit[]> {
    const docs = await this.prismaService.nonprofit.findMany();
    console.debug('NonprofitsService.findAll:', docs);
    return docs;
  }

Make sure that you have proper fields in GraphQL entities. For example in src/app/nonprofits/entities/nonprofit.entity.ts:

import { ObjectType, Field, Int, ID, GraphQLISODateTime } from '@nestjs/graphql';

@ObjectType()
export class Nonprofit {
  @Field(() => ID, { description: 'ID' })
  id: number;
  @Field(() => GraphQLISODateTime, { description: 'Created at' })
  createdAt: Date;
  @Field(() => String, { description: 'Email' })
  email: string;
  @Field(() => String, { description: 'Name' })
  name: string;
}

Executing GraphQL Queries

To use it, open GraphQL Playground at http://localhost:3333/graphql

Then you can do a query such as:

{
  nonprofits {
    id, createdAt, email, name
  }
}

To manipulate database contents, you can use your favorite MySQL Client (like MySQL Workbench, etc.). You can also use Prisma Studio by running yarn nx model:studio or:

cd libs/model
../../node_modules/.bin/prisma studio

Auto-Generate GraphQL Resolver for CRUD Queries and Mutations

After using Prisma for some time (I have ever used TypeORM before, and also Mongoose and Typegoose), there are things that I like:

  1. prisma migrate
  2. prisma studio
  3. the generated client typings/code completion is really good (see below)

However, compared to TypeORM in NestJS:

  1. we still need to create entity/input/output classes with GraphQL decorators
  2. Autogenerate GraphQL CRUD: With TypeORM there’s @nestjsx/crud (that is unfortunately seems slow development). With Prisma and Apollo-Server there is Nexus, however there’s no “official” way to integrate with NestJS yet -> discussion here: https://github.com/graphql-nexus/nexus/issues/386

How can we help?