Features

Auto generate CRUD system from your schema.prisma file. Every model will have folder contain 3 files

  • X.module.ts contain GraphQLModule for this model.
  • typeDefs.ts contain graphql types for this model.
  • resolvers.ts contain 3 queries and 6 mutations:
    • findUnique
    • findFirst
    • findMany
    • findCount
    • aggregate
    • createOne
    • updateOne
    • upsertOne
    • deleteOne
    • updateMany
    • deleteMany

Example Usage

For more information about Prisma look at they Docs

schema.prisma

datasource postgresql {
  url      = env("DATABASE_URL")
  provider = "postgresql"
}
generator client {
  provider = "prisma-client-js"
}
model User {
  id        Int      @id @default(autoincrement())
  createdAt DateTime @default(now())
  email     String   @unique
  name      String?
  role      Role     @default(USER)
  posts     Post[]
}
model Post {
  id         Int        @id @default(autoincrement())
  createdAt  DateTime   @default(now())
  updatedAt  DateTime   @updatedAt
  published  Boolean    @default(false)
  title      String
  author     User?      @relation(fields:  [authorId], references: [id])
  authorId   Int?
}
enum Role {
  USER
  ADMIN
}

After build your schema.prisma file all you need to run

prisma generate
pal g
  • build prisma client
  • auto generate your crud system for more information about pal g command configurations click here

Output For User Model

import gql from 'graphql-tag';

export default gql`
  type User {
    id: Int!
    createdAt: DateTime!
    email: String!
    name: String
    password: String!
  }

  type Query {
    findUniqueUser(where: UserWhereUniqueInput!): User
    findManyUser(
      where: UserWhereInput
      orderBy: UserOrderByInput
      cursor: UserWhereUniqueInput
      skip: Int
      take: Int
    ): [User!]
    findManyUserCount(
      where: UserWhereInput
      orderBy: UserOrderByInput
      cursor: UserWhereUniqueInput
      skip: Int
      take: Int
    ): Int!
  }
  type Mutation {
    createOneUser(data: UserCreateInput!): User!
    updateOneUser(where: UserWhereUniqueInput!, data: UserUpdateInput!): User!
    deleteOneUser(where: UserWhereUniqueInput!): User
    upsertOneUser(where: UserWhereUniqueInput!, create: UserCreateInput!, update: UserUpdateInput!): User
    deleteManyUser(where: UserWhereInput): BatchPayload
    updateManyUser(where: UserWhereInput, data: UserUpdateManyMutationInput): BatchPayload
  }
`;

Merge all modules

src/app/application.ts

import { createApplication } from 'graphql-modules';
import { InputsModule } from './inputs/inputs.module';
import { CommonModule } from './common/common.module';
import { addSelect } from './addSelect';
import { PrismaProvider } from './Prisma.provider';

export const application = createApplication({
  modules: [InputsModule, CommonModule],
  providers: [PrismaProvider],
  middlewares: {
    '*': { '*': [addSelect] },
  },
});

create inputs.module.ts

Create the inputs module to share will all modules to use Prisma and inputs

src/app/inputs/inputs.module.ts

import { createModule } from 'graphql-modules';
import { sdlInputs } from '@paljs/plugins';
export const InputsModule = createModule({
  id: 'Inputs',
  typeDefs: sdlInputs(),});

create Prisma.provider.ts

create Prisma instance and add onDelete plugin to it

src/app/Prisma.provider.ts

import { PrismaDelete, onDeleteArgs } from '@paljs/plugins';
import { Injectable, OnDestroy } from 'graphql-modules';
import { PrismaClient } from '@prisma/client';

@Injectable()
export class PrismaProvider extends PrismaClient implements OnDestroy {
  constructor() {
    super();
    this.$connect();
  }
  onDestroy(): void {
    this.$disconnect();
  }

  async onDelete(args: onDeleteArgs) {
    const prismaDelete = new PrismaDelete(this);
    await prismaDelete.onDelete(args);
  }
}

Add select object to args

It's a small tool to convert info: GraphQLResolveInfo to select object accepted by prisma client this will give you the best performance because you will just query exactly what you want

This middleware is take info and convert it to Prisma select object and add to resolve args

src/app/addSelect.ts

import { PrismaSelect } from '@paljs/plugins';

export const addSelect = (context, next) => {
  const result = new PrismaSelect(context.info).value;
  if (!result.select || Object.keys(result.select).length > 0) {
    context.args = {
      ...context.args,
      ...result,
    };
  }
  return next();
};