Build a serverless Prisma API for Vercel (example included!)

Do you have a great idea but aren't well versed in SQL and don't want to break the bank with a server and database? Then this guide is for you! You can set up a serverless API with Prisma and host it on Vercel for free.

I've never been great with APIs. I work on the web and on mobile and front end is my thing. However, sometimes even if you're not a backend guy you might need to set up an API for a side project. While this can sound like a gargantuan task it doesn't need to be!

I was struggling with the whole API thing a couple of months back. But then thankfully I stumbled upon Prisma which ended up saving me.

What is Prisma?

Prisma is a modern ORM (Object Relational Mapping) built for Typescript and Node.js which allows you to build solid and complex APIs in both Graphql and Rest with minimal effort.

Put simply, thanks to automatically generated types for your database, Prisma allows you to use a beautifully simple syntax to send queries to a database of choice. For example, finding a user is as easy as doing:

const result = await prisma.user.findUnique({
  where: {
    id: 42
  }
});

Prisma is a fantastic tool. But I still didn't want to rent a whole server to host my API, so I turned to serverless solutions to minimise costs.

Hosting my Prisma API on Vercel

Vercel is usually my go-to serverless solution. I love Next.js and often use it for my frontends, so it was just natural to keep my API in the same place.

Prisma does have a ready-to-go example to host on Vercel, but as I soon learned after testing it out, it... doesn't quite work. It was built with an older version of Vercel and things have changed since then.

The Code

I know, I know, get to the point. You can find the ready-to-go code for the Serverless Prisma API on Vercel on Github. Feel free to clone that and use it for your own projects.

There are a couple of quirks that you should know about before diving in, though. So read on unless you want to spend hours figuring it out through trial and error!

Setting up your Serverless Prisma API

First things first: the code depends on four environment variables.

  • DATABASE_URL: a connection string to your database of choice. If you want to test the API without commitment, check out Heroku's hobby database offering. You can set one up in minutes and it will be free forever.
  • ACCESS_TOKEN: a user's access token. The boilerplate currently uses this to test user permissions.
  • APP_SECRET: used to encrypt and decrypt JWTs. Keep it as the default value while testing or ACCESS_TOKEN will stop working in tests. (You've been warned!)
  • ALLOWED_ORIGIN: origin allowed by CORS. Make sure you change this depending on where you're connecting to your API from.

Once these are set up you can run npm run dev and try it out! Then if you want to test out your API you can use these example requests from Postman.

What's included in the API

For this boilerplate I wanted to make sure to include a lot of things that took me a while to figure out:

  • Authentication
  • Protected routes
  • Testing
  • Seeding and resetting

There's really simple examples for all of these in the repository. But if you have any questions about any of what's included, please feel free to open an issue and I'll try my best to give you a hand with it 😊.

Expanding and improving your API

At the moment all queries and mutations are kept in their respective files under api/_lib. If you want to expand them it's as simple as adding more definitions by following Prisma's CRUD documentation.

If you want to add more granular permissions I would suggest you check out the Graphql Shield repository. You'll find the implementation is fairly straight forward.

If you're looking to validate inputs before sending them to your database I suggest you look into Yup. I haven't included it in the repo, but it should be super simple to implement.

Deploying your Prisma API to Vercel

Deploying your serverless Prisma API to Vercel is very simple:

From now on all pushes to your repository will be automatically deployed on Vercel. Yes, even branches!

Caveats and stuff to look out for when deploying to Vercel

Vercel caches apps' node_modules folders. This is done to reduce network requests as node_modules can become absolutely massive. When Vercel detects changes and starts a new deploy, it will check if your package-lock.json is any different than its previous version. If it isn't then Vercel will simply download a cached version of your node_modules folder.

Why is this important? Well, unfortunately Prisma generates its types in node_modules/.prisma/client. This means that if you've made any changes to your schema (eg. if you wanted to add blog posts that your users can post), Prisma won't know those changes have happened until the cache is overwritten.

Luckily there's a really quick workaround that involves adding a postinstall script to package.json. This ensures that types are generated after every install, even if that install is cached!

Conclusion

The code should hopefully speak for itself. I've tried to keep things as simple as possible for this exact reason, but if you run into problems creating your serverless Prisma API on vercel, don't worry! If you have any questions or improvements to suggest, feel free to open an issue or submit a PR. I'll be monitoring the repository for a good while!