Skip to content

Prisma

Prisma is an ORM that allows us to interact with databases in a type-safe manner.

It provides a way to define your database schema using a Prisma schema file, and then generates TypeScript types based on that schema.

Prismabox

Prismabox is a library that generate TypeBox or Elysia validation models from Prisma schema.

We can use Prismabox to convert Prisma schema into Elysia validation models, which can then be used to ensure type validation in Elysia.

Here's how it works:

  1. Define your database schema in Prisma Schema.
  2. Add prismabox generator to generate Elysia schema.
  3. Use the converted Elysia validation models to ensure type validation.
  4. OpenAPI schema is generated from Elysia validation models.
  5. Add Eden Treaty to add type-safety to your frontend.
                                                    * ——————————————— *
                                                    |                 |
                                               | -> |  Documentation  |
* ————————— *             * ———————— * OpenAPI |    |                 |
|           |  prismabox  |          | ——————— |    * ——————————————— *
|  Prisma   | —————————-> |  Elysia  |
|           |             |          | ——————— |    * ——————————————— *
* ————————— *             * ———————— *   Eden  |    |                 |
                                               | -> |  Frontend Code  |
												    |                 |
												    * ——————————————— *

Installation

To install Prisma, run the following command:

bash
bun add @prisma/client prismabox && \
bun add -d prisma

Prisma schema

Assuming you already have a prisma/schema.prisma.

We can add a prismabox generator to the Prisma schema file as follows:

ts
generator client {
  provider = "prisma-client-js"
  output   = "../generated/prisma"
}

datasource db {
  provider = "sqlite"
  url      = env("DATABASE_URL")
}

generator prismabox { 
  provider = "prismabox"
  typeboxImportDependencyName = "elysia"
  typeboxImportVariableName = "t"
  inputModel = true
  output   = "../generated/prismabox"
} 

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

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

This will generate Elysia validation models in the generated/prismabox directory.

Each model will have its own file, and the models will be named based on the Prisma model names.

For example:

  • User model will be generated to generated/prismabox/User.ts
  • Post model will be generated to generated/prismabox/Post.ts

Using generated models

Then we can import the generated models in our Elysia application:

ts
import { Elysia, t } from 'elysia'

import { PrismaClient } from '../generated/prisma'
import { UserPlain, UserPlainInputCreate } from '../generated/prismabox/User'

const prisma = new PrismaClient()

const app = new Elysia()
    .put(
        '/',
        async ({ body }) =>
            prisma.user.create({
                data: body
            }),
        {
            body: UserPlainInputCreate, 
            response: UserPlain 
        }
    )
    .get(
        '/id/:id',
        async ({ params: { id }, status }) => {
            const user = await prisma.user.findUnique({
                where: { id }
            })

            if (!user) return status(404, 'User not found')

            return user
        },
        {
            response: {
                200: UserPlain, 
                404: t.String() 
            }
        }
    )
    .listen(3000)

console.log(
    `🦊 Elysia is running at ${app.server?.hostname}:${app.server?.port}`
)

This allows us to reuse the database schema in Elysia validation models.


For more information, please refer to the Prisma, and Prismabox documentation.