This tutorial is out of date and no longer maintained.
Besides the many hours of grunt work that Prisma saves by generating our CRUD operations for us, it also gives us access to a few other features that’ll save us even more time and give us more sophisticated control over our data structure. In this article, we’re going to be exploring some of the most common directives you’ll be using in your schemas.
Were going to be doing things that will help enhance our schemas, so you can refresh on the basics here.
You’re also going to need a basic Prisma container setup with a database of your choice. You can either check out this article or setting up Prisma with Docker, or you can just copy this repo and deploy it onto a new container.
Imagine we have an app and we want to add a new user while securing our app against users with the same email. Instead of having to manually send a query and check if a match already exists before saving something to the database, Prisma gives us a handy @unique
directive that’ll handle it for us. ID’s have their own special equivalent, just called @id
, which does basically the same thing.
type User {
id: ID! @id
name: String!
email: String! @unique
age: Int!
}
With that we can have a condition to tell the user it wasn’t available when a mutation fails.
Many times we obviously don’t want to make the user fill out everything their account may need, like whether they’re a basic user or an admin. It would be very useful to be able to add default values for those types of data.
The simplest way of handling that would be to just use the @default
directive to add a placeholder value.
type User {
id: ID! @id
name: String!
email: String! @unique
type: UserType! @default(value: USER)
}
enum UserType {
USER
ADMIN
}
Our data structures aren’t going to be built once and used forever, we eventually going to need to change some things around. While Prisma is pretty good about adding and removing new properties and types, it can have some problems when you want to rename a type that already has saved data reliant on it.
@rename
is a temporary directive, meaning that we just use it once, redeploy our schema, then remove it from datamodel.graphql
.
type User {
id: ID! @id
name: String!
email: String!
posts: [Content!]
}
type Content {
id: ID! @id
title: String! @unique
body: String!
author: User!
}
Content
is a pretty vague name, let’s use @rename
to change it to something a bit more explicit.
type User {
id: ID! @id
name: String!
email: String!
posts: [Content!]
}
type Post @rename(oldName: "Content") {
id: ID! @id
title: String! @unique
body: String!
author: User!
}
Move into your prisma
folder and redeploy your schema.
$ prisma deploy
Now you can safely remove @rename
without messing up your data.
The most useful and common thing you’ll be doing with directives is setting up relationships between your data types.
If we removed a product from our store, we would obviously want to remove every review for it from the database. If we were to delete the owner of that product we’d remove their products and the subsequent reviews. The problem is there needs to be a specific way of organizing this hierarchy, because we wouldn’t want to remove the user when their product or a review is removed.
The @relation
directive solves this problem pretty elegantly, we just need to pass a name that will link the two types together and tell it what we want done onDelete
, Either to stop or continue the deletions down the chain. CASCADE
will delete the type on the other side of the chain, while SET_NULL
will leave it.
type User {
id: ID! @id
name: String!
selling: [Product!] @relation(name: "UserToProduct", onDelete: CASCADE)
}
type Product {
id: ID! @id
name: String!
seller: User! @relation(name: "UserToProduct", onDelete: SET_NULL)
reviews: [Review!] @relation(name: "ProductToReview", onDelete: CASCADE)
}
type Review {
id: ID! @id
author: User!
review: String!
product: Product! @relation(name: "ProductToReview", onDelete: SET_NULL)
}
There are a few more options that are worth checking out over in the official docs.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
Join our DigitalOcean community of over a million developers for free! Get help and share knowledge in our Questions & Answers section, find tutorials and tools that will help you grow as a developer and scale your project or business, and subscribe to topics of interest.
Sign up nowThis textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!