Easy, type-safe database Access in Fastify servers

Query data from MySQL, PostgreSQL & SQL Server databases in Fastify apps with Prisma – a better ORM for JavaScript and TypeScript.

Why Prisma and Fastify?

Flexible architecture

Prisma fits perfectly into your stack, no matter if you're building microservices or monolithic apps.

Higher productivity

Prisma's gives you autocompletion for database queries, great developer experience and full type safety.

Type-safe database client

Prisma Client ensures fully type-safe database queries with benefits like autocompletion - even in JavaScript.

Intuitive data modeling

Prisma's declarative modeling language is simple and lets you intuitively describe your database schema.

Easy database migrations

Generate predictable and customizable SQL migrations from the declarative Prisma schema.

Designed for building APIs

Prisma Client reduces boilerplates by providing queries for common API features (e.g. pagination, filters, ...).

How Prisma and Fastify fit together

Prisma ORM is a next-generation ORM that's used to query your database in a Fastify server. You can use it as an alternative to writing plain SQL queries, query builders like knex.js or traditional ORMs like TypeORM, MikroORM and Sequelize.

REST API

Prisma is used inside your route handlers to read and write data in your database.

import fastify from 'fastify'
import { PrismaPg } from '@prisma/adapter-pg'
import { PrismaClient } from '../generated/client'

const adapter = new PrismaPg({
  connectionString: process.env.DATABASE_URL,
})
const prisma = new PrismaClient({ adapter })
const app = fastify()

app.get('/feed', async (req, res) => {
  const posts = await prisma.post.findMany({
    where: { published: true },
    include: { author: true },
  })
  res.json(posts)
})

app.post('/post', async (req, res) => {
  const { title, content, authorEmail } = req.body
  const post = await prisma.post.create({
    data: { title, content, published: false, author: { connect: { email: authorEmail } } },
  })
  res.json(post)
})

app.listen(3000)

prismaPlugin

Fastify allows you to extend its functionality with plugins. You can create a plugin to instantiate and expose the Prisma Client instance to the rest of your application via the Fastify server instance.

import fp from 'fastify-plugin'
import { FastifyPluginAsync } from 'fastify'
import { PrismaPg } from '@prisma/adapter-pg'
import { PrismaClient } from '../generated/client'

declare module 'fastify' {
  interface FastifyInstance { prisma: PrismaClient }
}

const prismaPlugin: FastifyPluginAsync = fp(async (server, options) => {
  const prisma = new PrismaClient({
    adapter: new PrismaPg({
      connectionString: process.env.DATABASE_URL,
    }),
  })
  await prisma.$connect()
  server.decorate('prisma', prisma)
  server.addHook('onClose', async (server) => {
    await server.prisma.$disconnect()
  })
})

export default prismaPlugin

// server.ts
import fastify from 'fastify'
import prismaPlugin from './plugins/prisma'

const app = fastify()
app.register(prismaPlugin)
await app.listen(3000, '0.0.0.0')

GraphQL API

When building GraphQL APIs with Prisma, you use Prisma Client inside your resolver functions to read and write data in your database.

Learn more about Prisma with GraphQL.

import fastify from 'fastify'
import mercurius from 'mercurius'
import { PrismaPg } from '@prisma/adapter-pg'
import { PrismaClient } from '../generated/client'

const app = fastify()
const adapter = new PrismaPg({
  connectionString: process.env.DATABASE_URL,
})
const prisma = new PrismaClient({ adapter })

const typeDefs = `
  type User { email: String! name: String }
  type Query { allUsers: [User!]! }
`

const resolvers = {
  Query: { allUsers: () => prisma.user.findMany() }
}

app.register(mercurius, { schema: typeDefs, resolvers, graphiql: true })
app.listen(4000)

Prisma schema

The Prisma schema uses the Prisma schema language to define your database schema. It makes data modeling declarative and intuitive, especially when it comes to modeling relations.

model User {
  id    Int     @default(autoincrement()) @id
  name  String?
  email String  @unique
  posts Post[]
}

model Post {
  id        Int      @default(autoincrement()) @id
  published Boolean? @default(false)
  title     String
  content   String?
  author    User?    @relation(fields: [authorId], references: [id])
  authorId  Int?
}

Featured Prisma & Fastify examples

Monitoring your GraphQL API with Fastify, Mercurius, and Prisma

Exploring some of the practices to ensure the reliable operation of a GraphQL server in addition to helping with production troubleshooting.

Fastify REST API starter kit

A ready-to-run example project for a REST API with a SQLite database.

Fastify GraphQL API starter kit

A ready-to-run example project for a GraphQL API with a PostgreSQL database.