3. Add the .env file to include DATABASE_URL and if the auth module is included add SALT, JWT_SECRET
Please make sure you have a postgres database created and it matches .env
config for more info please consult Prisma docs[https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema]).
This will also regenerate prisma client and the NestJs GraphQL types in the src/@generated
folder based on the generator.
You could use the config from use-generated-config/appconfig_example.json
along with copying the contents of use-generated-config/schema.prisma__example
to prisma/schema.prisma
as a working starting point. Also if auth module is used make sure you have SALT
and JWT_SECRET
in .env
defined as per .env__example
Optionally, run npx use-generated generate config
to generate a starting point in your appconfig.json
With this CLI you will be able to create a fully customizable and extendable Graphql CRUD API just by defining the database or data models and a configuration file
allUsers
- accepts properties:
perPage
- used for paginationskip
- used for paginationorderBy
sorting / ordering, matches the Prisma ORMorderBy
APIwhere
filtering matches the Prisma ORMwhere
nestedArgs
defines theperPage
,skip
,orderBy
andwhere
for the nested relations
Example: query:
query users($nestedArgs:UserNestedArgsStartPoint,$where:UserWhereInput) {
allUsers(where:$where,nestedArgs:$nestedArgs){
id
email
comments {
id
content
likes {
id
userId
}
}
}
}
variables:
{
"where": {"email": {"equals": "second@email.com"}}
"nestedArgs": {
"comments": {
"args": {
"where": {"id": {"gte": 2 }}
},
"likes":{
"args": {
"where": {"userId": {"gte": 10 }}
},
}
}
}
}
results:
{
"data": {
# allUsers results is filtered by where
"allUsers": [
{
"id": "2",
"email": "second@email.com",
# comments list is filtered by 'nestedArgs.comments.args.where' property
"comments": [
{
"id": "2",
"content": "hey there is the second comment"
# likes list is filtered by nestedArgs.comments.likes.args.where property
"likes": [
{
"id": "2",
"userId":"10"
},
{
"id": "2",
"userId":"11"
}
]
},
{
"id": "3",
"content": "Here is the third comment",
"likes": [
{
"id": "2",
"userId":"12"
}
]
}
]
}
]
}
}
User
-get one user by id accepts properties:
id
nestedArgs
same as forallUsers
defines theperPage
,skip
,orderBy
andwhere
for the nested relations Example query
query users($nestedArgs:UserNestedArgsStartPoint,$id:Int!) {
User(id:$id,nestedArgs:$nestedArgs){
id
email
comments {
id
content
}
}
}
Variables:
{
"nestedArgs": {
"comments": {
"args": {"where": {"id": {"gte": 2 }}}
}
},
"id": 1
}
}
Results:
{
"data": {
"User": {
"id": "1",
"email": "firstuseremail",
"comments": [
{
"id": "3",
"content": "hey there third comment"
}
]
}
}
}
_allUsersMeta
- count
generated mutations based on the default templates
Considering a model called User
:
createUser
, updateUser
, deleteUser
,updateManyUsers
For full documentation please check https://www.prisma.io/docs/getting-started/setup-prisma/start-from-scratch/relational-databases-typescript-postgres
Here is a sample schema.prisma file where the data models are defined
generator client {
provider = "prisma-client-js"
}
// connection to the a postgress database. make sure there is a DATABASE_URL variable in the .env file
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator nestgraphql {
provider = "node node_modules/prisma-nestjs-graphql"
noAtomicOperations = "true"
reExport = "Directories"
output = "../src/@generated"
}
model User {
id Int @id @default(autoincrement())
email String @unique
passwordHash String? @unique
resetToken String? @unique
roles UserRole[]
// The foreign key from the Post.author is defined here as well explicit, if not defined there will be an error
posts Post[]
}
enum UserRole {
SuperAdmin
Admin
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean
// defines a foreign key to the User, the property on this object will be called author and the id of the relation "authorId" while the target connection field on the User is "id"
author User? @relation(fields: [authorId], references: [id])
authorId Int?
}
The Graphql API is generated based on the schema.prisma
file and appconfig.json
configuration file
Defines the folders in wich the models will be structured
name
- name of the foldermodels
-nest js models
-
name
- name of the module -
queryDepthLevel
- number, defining the depth level that relations can be interogated, it will override thedefaultQueryDepthLevel
from the root level. please keep in mind that setting a high number here will cause performance issues: for each relation there will be one query to the db. Example: -
queryDepthStructure
defines the structure of the relations that can be interogated Example: -
requireLogin
- If
true
all mutations and queries will require login. It will override thedefaultRequireLogin
from the root level. - If it's an array of strings it defines the list of queries and mutations for which login will be required
"requireLogin": [ "findAll", "create"]
- If
-
requiredRoles
- If it's an array of strings- it defines a list of roles that if a user has at least one can perform a query or a mutation for the model
- if it's an object should have the properties corresponding to the name of the queries and mutations { "findAll":["Admin"], "createItem":["SuperAdmin"] } Warning if one query of mutation is excluded in this object there will be no role applied, and if require login doesn't cover that mutation or query it will be left open without any authentication.
-
crud
- allows to defineresolverTemplate
andserviceTemplate
for this model. We recommend using the default ones as a starting point. Incorrect templates could cause properties above to not function as intended or even errors. pleasse see the templates section for more details
If true
all mutations and queries will require login unless there requireLogin is defined at model level. In that case the model level definition is applied.
If true
and a module called 'auth' doesn't exist at the root level, the default auth module that comes with this package will be copied over, if the folder already exists with the name 'auth' nothing will happen
The depth level that relations can be interogated, if ueryDepthLevel
is defined at the module level this prop will be ignored
If true
and a module called 'prisma' doesn't exist at the root level, the default prisma module that comes with this package will be copied over, if the folder already exists with the name 'prisma' nothing will happen
If true
it creates a folder called commonTypes
at the root level containing ListMetadata
The generated resolvers and services are under {modelNameHere}/generated
Like so user/generated/user.generated-resolver.ts
, user/generated/user.generated-service
For overriding a method in service just add the modified method in user/user.generated-service.ts
that has the same name as one in the generated file. No need to delete the one from generated file.
It's generated by the "prisma-nestjs-graphql" module, based on the definitions in schema.prisma
generator nestgraphql {
provider = "node node_modules/prisma-nestjs-graphql"
noAtomicOperations = "true"
reExport = "Directories"
output = "../src/@generated"
}
It's recreated anytime prisma client is generated (yarn prisma generate
)
Contains GraphQL all the standard type definitions.