just some notes.

Relations, including nested data and more Prisma 2 notes

September 15, 2020

I’m currently exploring a new back-end technology called Prisma 2. I want to share some notes here, as I discover how it works, in the hope that they might be useful to anyone trying out Prisma 2 too (^-^). If you’re not into coding, javascript, graphql or all that stuff, it probably won’t be too interesting for you. Of course, you’re welcome to read the notes anyway.

A little background: Prisma 2 is the successor to Prisma, which is a database layer that provides you with easy access to a database. It’s done in graphql style, so you can make those nice ‘buffet’-like queries where you pick and choose the data you need.

The new Prisma mostly does the same thing as the previous Prisma, but it works completely different under the hood, which allows for us as developers to be a bit more explicit about how we use the technology. That usually also means we need to dive a little deeper into the stuff that was previously sheltered from us. Hence, here I am, discovering the ‘quirks’, or rather just how things work.

Schema

The Prisma 2 schema is where you model your database. You tell Prisma what you need and how things are related, and in turn it will set up the database for you.

Making the schema is for the most part quite intuitive. I highly recommend installing the VSCode plugin if you’re using VSCode. It immediately shows you when you make typos, or do any illegal stuff. Naturally with illegal stuff I mean instance where you are trying to create relations that are impossible or using scalar values that don’t exist.

Especially the relations need extra attention if you’re coming from the previous Prisma or even Graphcool. It isn’t quite as straightforward anymore as it was… but that’s for the best. That’s my feeling at least.

Prisma 2 relations

  • Many-to-many relations can be done implicitly or explicitly with a connection table between the two types. If you want to have fields on the connection, then a connection table is preferred. For most cases an implicit many-to-many will work.

  • One-to-one or one-to-many relations always needs a foreign key. If it’s one-to-many or many-to-one, it needs to be on the ‘one’. If it’s one-to-one you can choose on which model you place it.

  • If there are multiple relations to the same model on a model, you need to give the relation a name.

Setting up Prisma 2 with Apollo Server

After you’ve written out your database schema, have Prisma migrate your database, and then generate a corresponding schema for your back-end, you can worry about your server.

I am using a NodeJS server, and since I want to expose a graphql API to my frontend, I would like to use Apollo Server. It’s a solid and well-known technology that provides a lot of functionality.

How to setup Apollo Server in conjunction with Prisma 2 isn’t really properly documented anywhere at the time of writing. But you can definitely use Prisma 2 with Apollo Server without having to use stuff like Nexus. It’s actually quite easy.

The way I set it up is to simply configure the Apollo Server as you normally would, but then pass in Prisma 2 in the context.

const server = new ApolloServer({
    typeDefs,
    resolvers,
    context: createContext,
});

And your context function could look a little something like this:

const prisma = new PrismaClient();

function createContext({ req }) {
    const token = req.headers.authorization;
    // possibly do some authentication stuff
    // or maybe something else :)
    return { prisma, token };
}

That’s pretty much it.

Querying and Mutating

Finally you should be able to query and mutate from your Apollo Server. On gotcha I should give you a heads up about:

  • When you query nested types you need to either ‘include’ or ‘select’ them. The same goes for retrieving data after a mutation. This got me at first, where I wondered the better part of a day where my data went. The docs had the answer, but coming from the previous Prisma I just didn’t expect this behaviour.

I’ll update this entry as I gather more notes.