Skip to content

Latest commit

 

History

History
 
 

data-modelling

Data Modelling

This example demonstrates various data modelling features of Prisma.

Get started

Note: prisma is listed as a development dependency and script in this project's package.json. This means you can invoke the Prisma CLI without having it globally installed on your machine (by prefixing it with yarn), e.g. yarn prisma deploy or yarn prisma playground. If you have the Prisma CLI installed globally (which you can do with npm install -g prisma), you can omit the yarn prefix.

1. Download the example & install dependencies

Clone the Prisma monorepo and navigate to this directory or download only this example with the following command:

curl https://codeload.github.com/graphcool/prisma/tar.gz/master | tar -xz --strip=2 prisma-master/examples/data-modelling

Next, navigate into the downloaded folder and install the NPM dependencies:

cd data-modelling
yarn install

2. Deploy the Prisma database service

You can now deploy the Prisma service (note that this requires you to have Docker installed on your machine - if that's not the case, follow the collapsed instructions below the code block):

yarn prisma deploy
I don't have Docker installed on my machine

To deploy your service to a demo server (rather than locally with Docker), please follow this link.

3. Explore the generated datamodel

This example seeds some data into the database for us to explore some queries and features of the data model. Please take a look at seed.graphql for reference. Feel free to add/remove more data via mutations.

The easiest way to explore this deployed service and play with the API generated from the data model is by using the GraphQL Playground.

Open a Playground

You can either start the desktop app via

yarn playground

Or you can open a Playground by navigating to http://localhost:4466/data-modelling in your browser.

This example illustrates a few important concepts when working with your data model:

There are three types Tweet, User and Location

These types are mapped to tables in the database. We can query any of these types (say Tweet) in the following ways

Get one tweet by its id (or any other field with @unique directive)
query Tweet {
 tweet(where: { id: "<tweet-id>" }) {
  id
  text
 }
}
Get multiple tweets with pagination
query Tweets {
 tweets(first: 10, skip: 20) {
  id
  text
 }
}
Get multiple tweets sorted by their createdAt field value
query Tweets {
 tweets(orderBy: createdAt_DESC) {
  id
  text
 }
}
Get multiple tweets with conditions like tweet text should contain "GraphQL" string and it should not be from the user "Graphcool"
query Tweets {
 tweets(
  where: {
   AND: [{ text_contains: "GraphQL" }, { owner: { name_not: "Graphcool" } }]
  }
 ) {
  id
  text
 }
}

There is a bidirectional relation between User and Tweet

Get user for a tweet
query Tweets {
 tweets {
  id
  text
  owner {
   id
   name
  }
 }
}
Get tweets for a user and sort the tweets by their createdAt field.
query UserTweets {
 user(where: { handle: "graphcool" }) {
  id
  name
  tweets(orderBy: createdAt_DESC) {
   id
   text
  }
 }
}

GraphQL Directives

Unique

@unique - The @unique directive marks a scalar field as unique. Unique fields will have a unique index applied in the underlying database. In this data model, amongst other fields, the field handle on the type User is marked with @unique directive. Which is why we are able to query the user using their handle.

query UserTweets {
 user(where: { handle: "graphcool" }) {
  id
  name
 }
}
Relation

@relation - The directive @relation(name: String, onDelete: SET_NULL) can be attached to a relation field.

In this data model, we have added the following directive on tweets field in User type @relation(name: "UserTweets", onDelete: CASCADE)

The deletion behaviour in this example is as follows:

  • When a User node gets deleted, all its related Tweet nodes will be deleted as well.

  • When a Tweet node gets deleted, it will simply be removed from the tweets list on the related User node.

Note that deleteMany does not activate a cascade delete yet. This feature is being tracked here.

Default

@default - The directive @default(value: String!) sets a default value for a scalar field. Note that the value argument is of type String for all scalar fields (even if the fields themselves are not strings). In this data model, we have provided a @default directive on the name field of User type as @default(value: ""). This will set the default value to "" when it is not provided by a mutation.