2.5.5 • Published 3 months ago

prisma-generator-nestjs-graphql-crud v2.5.5

Weekly downloads
-
License
MIT
Repository
-
Last release
3 months ago

prisma-generator-nestjs-graphql-crud

This prisma generator will create all the @nestjs/graphql classes you'll need for basic CRUD operations; based on your prisma schema. It includes dataloader to prevent the infamous n+1 problem in graphql.

npm i prisma-generator-nestjs-graphql-crud

Getting Started

  1. Inside your prisma schema add the following:
generator nestJsGraphQlCrud {
  provider = "prisma-generator-nestjs-graphql-crud"
}

Options:

FeatureDescriptionDefaultExample
excludesprisma model names to exclude from generatorexcludes = ["Ignore"]
includeMutationsinclude mutation resolversincludeMutations = "true"
outputcwd relative path for the outputnode_modules/@generated/graphqloutput = "./example/src"
  1. Configure your Graphql Service In NestJs

The generated code relies on the context object for graphql to contain a reference to the prisma client. See the use of useFactory in the GraphQLModule below.

PrismaModule and PrismaService are generated; if you want your own custom implementation, use this doc as a guide.

* generated code is compatible with @nestjs/mercurius, @nestjs/apollo and @graphql-yoga/nestjs

import {
  DataLoaderService,
  PrismaModule,
  prismaProviders,
  PrismaService
} from '@generated/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';

@Module({
  imports: [
    GraphQLModule.forRootAsync<ApolloDriverConfig>({
      driver: ApolloDriver,
      inject: [DataLoaderService, PrismaService],
      useFactory: (loaders: DataLoaderService, prisma: PrismaService) => ({
        autoSchemaFile: 'schema.gql',
        context: (req: FastifyRequest, res: FastifyReply) => {
          return {
            loaders: loaders.create(),
            prisma,
            req,
            res
          };
        },
        graphiql: true
      })
    }),
    PrismaModule.forRoot({
      isGlobal: true
    })
  ],
  providers: [...prismaProviders]
})
export class AppModule {
}

Prisma Features

FeatureAvailableNotes
create
createMany
delete
deleteMany
findUniqueby primary key or composite keys
findManypagination included (skip/take only for now)
filtersgt,gte,lt,lte,notIn,in,not, etc. (DateTime, Int, String supported)
orderBy
update
updateMany

The following are the various filters and generated resolvers. Note the table name is Upper-CamelCased; e.g. user_session would become UserSession.


Resolvers

All the following are based on the example project found here.


create

Create a new entity. Here's an example:

mutation {
    createTodo(title: "Next Todo", userId: 1) {
        id
        title
        userId
    }
}

This would return the following:

{
  "data": {
    "createTodo": {
      "id": 6,
      "title": "Next Todo",
      "userId": 1
    }
  }
}

createMany

Create multiple new entities. Here's an example:

mutation {
    createManyTodo([{"title": "Another Todo", "userId": 1}, {"title": "Final Todo", "userId": 2}]) {
        id
        title
        userId
    }
}

This would return the following:

{
  "data": {
    "createManyTodo": [
      {
        "id": 7,
        "title": "Another Todo",
        "userId": 1
      },
      {
        "id": 8,
        "title": "Final Todo",
        "userId": 2
      }
    ]
  }
}

delete

Delete an entity. Here's an example:

mutation {
    deleteTodo(id: 1) {
        id
        title
        userId
    }
}

This would return the following:

{
  "data": {
    "deleteTodo": {
      "id": 1,
      "title": "First Todo",
      "userId": 1
    }
  }
}

deleteMany

Delete multiple entities. Here's an example:

mutation {
    deleteManyTodo(userId: 1) {
        id
        title
        userId
    }
}

This returns the list of deleted todos:

{
  "data": {
    "deleteManyTodo": [
      {
        "id": 1,
        "title": "First Todo",
        "userId": 1
      },
      {
        "id": 2,
        "title": "Second Todo",
        "userId": 1
      }
    ]
  }
}

findFirst

Find first should be used when you want to query and find a single row without using any of the unique keys for filters; this means that any filters you use for a findMany can be used here. Here's an example:

query {
    findFirstTodo(title: "That Todo") {
        id
        title
        userId
    }
}

This would return the following:

{
  "data": {
    "findFirstTodo": {
      "id": 1,
      "title": "That Todo",
      "userId": 1
    }
  }
}

findMany

Find many is used to return either filtered or unfiltered rows from a table, and can optionally provide skip (offset) and take (limit) as parameters to control pagination. Here's an example:

query {
    findManyTodo(skip: 0, take: 5) {
        id
        title
        userId
    }
}

This would return the following:

{
  "data": {
    "findManyTodo": [
      {
        "id": 1,
        "title": "Todo 1",
        "userId": 1
      },
      {
        "id": 2,
        "title": "Todo 2",
        "userId": 1
      },
      {
        "id": 3,
        "title": "Todo 3",
        "userId": 1
      },
      {
        "id": 4,
        "title": "Todo 4",
        "userId": 2
      },
      {
        "id": 5,
        "title": "Todo 5",
        "userId": 2
      }
    ]
  }
}

findUnique

Find unique should be used when you want to query against a primary key or composite key. Here's an example:

query {
    findUniqueTodo(id: 1) {
        id
        title
        userId
    }
}

This would return the following:

{
  "data": {
    "findUniqueTodo": {
      "id": 1,
      "title": "Todo 1",
      "userId": 1
    }
  }
}

update

Updates a single entity. Here's an example:

mutation {
    updateTodo(data: {"title": "First Todo", "userId": 2}, where: {"id": 1}) {
        id
        title
        userId
    }
}

This would return the following:

{
  "data": {
    "updateTodo": {
      "id": 1,
      "title": "First Todo",
      "userId": 2
    }
  }
}

updateMany

Updates a single entity. Here's an example:

mutation {
    updateManyTodo(data: {"userId": 2}, where: {"userId": 1}) {
        id
        title
        userId
    }
}

This would return the following:

{
  "data": {
    "updateManyTodo": [
      {
        "id": 1,
        "title": "First Todo",
        "userId": 2
      },
      {
        "id": 2,
        "title": "Second Todo",
        "userId": 2
      }
    ]
  }
}

Filters

The following filters are available are:


DateFilter

TypeSupported
findFirst
findMany
findUnique

Options

TypeDescriptionExample
gtwhere the column value is greater than the given {value}gt: "2022-01-10"
gtewhere the column value is greater than or equal to the given {value}gte:"2022-01-10"
ltwhere the column value is less than the given {value}lt: "2022-01-10"
ltewhere the column value is less than or equal to the given {value}lte:"2022-01-10"
notwhere the column value is not equal to the given {value}not: "2022-01-10"

Example:

query {
    findManyTodo(createdAt: { gt: "2022-01-10", lt: "2023-01-10" }) {
        id
        title
    }
}

NumberFilter

TypeSupported
findFirst
findMany
findUnique

Options

TypeDescriptionExample
gtwhere the column value is greater than the given {value}gt: 1
gtewhere the column value is greater than or equal to the given {value}gte: 1
ltwhere the column value is less than the given {value}lt: 1
ltewhere the column value is less than or equal to the given {value}lte: 1
notwhere the column value is not equal to the given {value}not: 1

Example:

query {
    findManyTodo(userId: { gt: 1, lt: 2 }) {
        id
        title
        userId
    }
}

OrderBy

TypeSupported
findFirst
findMany
findUnique

Example:

query {
    findManyTodo(skip: 0, take: 5, orderBy: {title: "desc"}) {
        id
        title
    }
}

StringFilter

TypeSupported
findFirst
findMany
findUnique

Options

TypeDescriptionExample
containswhere the column contains the given {value}contains: "Robert"
endsWithwhere the column value ends with the {value}endsWith: "ert"
inwhere the column contains a value matching the array of {values}sin: "Robert", "Rob"
notwhere the column value does not not equal the {value}not: "Matt"
notInwhere the column does not contain a value matching the array of {values}snotIn: "robb", "Robb"
startsWithwhere the column value starts with the {value}startsWith: "Rob"

*all are case-insensitive

Example:

query {
    findManyTodo(title: { contains: "First" }) {
        id
        title
    }
}

Skip (offset)

TypeSupported
findFirst
findMany
findUnique

Example:

query {
    findManyTodo(skip: 0) {
        id
        title
    }
}

Take (limit)

TypeSupported
findFirst
findMany
findUnique

Example:

query {
    findManyTodo(take: 10) {
        id
        title
    }
}

Graphql Features

FeatureAvailableNotes
FieldResolversboth up and down relationships supported
Mutations
Query
Resolvers

Example

See a generated example here; note, when the output is in a node_modules directory, it will automatically transpile cjs and mjs versions.


Road Map

  • authentication guard integration
  • cursor-based pagination
  • expand gt, gte, lt, lte, notIn, in, not "where" filtering to types other than DateTime, Int, and String

TODO

  • fix orderBy ArgTypes casting to Prisma.{Model}FindManyArgs['orderBy']
  • fix data ArgTypes casting to Prisma.{Model}CreateArgs['data']
  • fix where ArgTypes casting to Prisma.{Model}FindManyArgs['where']
2.5.2

3 months ago

2.5.1

3 months ago

2.5.4

3 months ago

2.5.3

3 months ago

2.5.5

3 months ago

2.5.0

3 months ago

2.4.0

4 months ago

2.3.1

7 months ago

2.3.0

8 months ago

2.2.1

8 months ago

2.1.2

8 months ago

2.2.0

8 months ago

2.1.1

8 months ago

2.1.4

8 months ago

2.2.2

8 months ago

2.1.3

8 months ago

2.1.6

8 months ago

2.1.5

8 months ago

2.1.7

8 months ago

2.1.0

8 months ago

2.0.0

9 months ago

1.1.5

1 year ago

1.1.4

1 year ago

1.1.3

1 year ago

1.1.2

1 year ago

1.1.1

1 year ago

1.1.0

1 year ago

1.0.3

1 year ago

1.0.2

1 year ago

1.0.0

1 year ago