Overview

This guide explains how to upgrade from Graphcool to Prisma 2.

Note: The Graphcool servers are gradually shut down from July 1st onwards. Please reach out to us if you have a mission-critical application running on Graphcool and are not able to migrate away from Graphcool until July 1st.

Considerations before upgrading

BaaS vs Prisma

Prisma is not a Backend-as-a-Service but a database toolkit. This means that it unfortunately can't provide the same level of convenience you're used to from Graphcool. When choosing Prisma for the future of your application, you will have to implement and host your own backend which includes the GraphQL API server as well as the database.

Evolving the application and changing the database schema

Prisma unfortunately doesn't have a production-ready solution for running schema migrations against a database yet. This means that if you migrate to Prisma and want to evolve your application in the future, you'll need to migrate your database schema manually using SQL or another migration tool like Flyway (until Prisma Migrate is considered production-ready).

Implementing an API server (including authentication & authorization)

We recommend using GraphQL Nexus with the nexus-plugin-prisma to quickly expose GraphQL CRUD operations in your API server without much boilerplate.

However, in case you need to restrict data access in the API with dedicated authorization rules (i.e. permissions queries in Graphcool), this approach won't work and you will have to implement all queries and mutations individually and add your own authorization rules, e.g. using graphql-shield.

Implementing GraphQL subscriptions

Prisma doesn't have a realtime API that could be used to implement GraphQL subscriptions. Subscriptions can be implemented by manually triggering them inside of a resolver or based on native database triggers.

Upgrade alternatives

Because Graphcool and and Prisma 2 are very different, it might be a viable option to migrate to another more BaaS-like provider, such as:

Note: Feel free to reach out to us directly if you have any questions about the migration path.

Migration path

On a high-level, the migration path from Graphcool to Prisma 2 looks as follows:

  1. Create SQL dump of Graphcool project using the Graphcool Exporter
  2. Import the dump into a MySQL database
  3. Introspect your database with Prisma 2.0
  4. Create CRUD GraphQL API with Nexus (and optionally nexus-plugin-prisma)

1. Create a SQL dump of your Graphcool project

Open the Graphcool Exporter at https://export.graph.cool/.

Then grab your permanent auth token from the Settings > Authentication > Permanent Auth Tokens area in the Graphcool console and paste it into the text field. Now click Export.

This downloads a zipped .sql file with a dump of all the data that's stored in your Graphcool project.

2. Import the SQL dump into your own MySQL database

Follow the guide that explains how to import data into a MySQL database.

3. Introspect your database with Prisma 2

At this point, you have a MySQL database with the same data that you had in your Graphcool project. You can now setup your new npm project that you'll use to implement the GraphQL API:

1npm init -y

With your new npm project in place, you can follow the guide that explains how to add Prisma to an existing project.

Note that Graphcool uses the same data modeling approach as Prisma 1. If you encounter any schema incompatibilies, you can resolve them in the same way as if you were upgrading from Prisma 1.

4. Create CRUD GraphQL API

The last step in the migration process is to expose CRUD operations in your GraphQL API. The recommended approach for this is to use Nexus and the nexus-plugin-prisma. The plugin allows you to directly expose your Prisma models via GraphQL.

Once you installed the required dependencies in your project, you can add the nexus-plugin-prisma as follows:

1import { use } from 'nexus'
2import { prisma } from 'nexus-plugin-prisma'
3
4use(prisma({ migrations: false }))

The last line gives you access to the t.model and t.crud fields when defining your GraphQL schema with Nexus. Both fields enable you to

Here is an example, assume you have the following Prisma schema:

1model Category {
2 id String @id
3 name String
4 Post Post[] @relation(references: [id])
5}
6
7model Post {
8 authorId String?
9 content String?
10 createdAt DateTime @default(now())
11 id String @id
12 published Boolean @default(false)
13 title String
14 updatedAt DateTime @default(now())
15 Category Category[] @relation(references: [id])
16}
17
18model Profile {
19 bio String?
20 id String @id
21 user String? @unique
22 User User? @relation(fields: [user], references: [id])
23}
24
25model User {
26 email String? @unique
27 id String @id
28 jsonData Json?
29 name String
30 role User_role? @default(CUSTOMER)
31 Profile Profile?
32}
33
34enum User_role {
35 ADMIN
36 CUSTOMER
37}

Here's how you can ensure all your models are exposed via GraphQL:

1schema.objectType({
2 name: 'User',
3 definition(t) {
4 t.model.id()
5 t.model.email()
6 t.model.name()
7 t.model.jsonData()
8 t.model.role()
9 t.model.profile()
10 t.model.posts({
11 filtering: true,
12 ordering: true,
13 })
14 },
15})
16
17schema.objectType({
18 name: 'Post',
19 definition(t) {
20 t.model.id()
21 t.model.createdAt()
22 t.model.updatedAt()
23 t.model.title()
24 t.model.content()
25 t.model.published()
26 t.model.author()
27 t.model.authorId()
28 t.model.categories({
29 filtering: true,
30 ordering: true,
31 })
32 },
33})
34
35schema.objectType({
36 name: 'Profile',
37 definition(t) {
38 t.model.id()
39 t.model.bio()
40 t.model.user()
41 t.model.userId()
42 },
43})
44
45schema.objectType({
46 name: 'Category',
47 definition(t) {
48 t.model.id()
49 t.model.name()
50 t.model.posts({
51 filtering: true,
52 ordering: true,
53 })
54 },
55})

Finally, you can expose CRUD operations for all your models via t.crud when defining your Query and Mutation types with Nexus. For example, if you want to enable all the CRUD operations for the User model, you can do it as follows:

1schema.queryType({
2 definition(t) {
3 t.crud.user()
4 t.crud.users({
5 pagination: true,
6 filtering: true,
7 ordering: true,
8 })
9 },
10})
11
12schema.mutationType({
13 definition(t) {
14 t.crud.createOneUser()
15 t.crud.updateOneUser()
16 t.crud.deleteOneUser()
17 },
18})
Edit this page on Github