Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(recipes): prisma usage #58

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
187 changes: 187 additions & 0 deletions docs/content/docs/3.recipes/3.prisma.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
---
title: Prisma ORM
description: Learn how to setup Prisma ORM with NuxtHub.
---

::alert{icon="i-ph-warning" color="red" title="WIP"}
This ORM is not fully compatible with NuxtHub yet.
:br
- [Migrations](#migrations) are not supported yet.
atinux marked this conversation as resolved.
Show resolved Hide resolved
- Deployment has an addressed issue, that will be solved soon ([unwasm/issues#21](https://github.com/unjs/unwasm/issues/21){target=_blank}).
::

::callout{icon="i-ph-link" to="https://www.prisma.io/orm" external}
Learn more about **Prisma ORM**.
::

## Setup

To enhance your Developer Experience with the database, we can create a `usePrisma()` server composable with few steps.
atinux marked this conversation as resolved.
Show resolved Hide resolved

### Install Prisma

1. Install the `prisma`, `@prisma/adapter-d1` and `@prisma/client` packages to your project:

::code-group
```bash [pnpm]
pnpm add prisma @prisma/adapter-d1 @prisma/client
```
```bash [yarn]
yarn add prisma @prisma/adapter-d1 @prisma/client
```
```bash [npm]
npm install prisma @prisma/adapter-d1 @prisma/client
```
```bash [bun]
bun add prisma @prisma/adapter-d1 @prisma/client
```
::
atinux marked this conversation as resolved.
Show resolved Hide resolved

### Init Prisma

To init Prisma and generate its schema file, run this command:

```bash
npx prisma init --datasource-provider sqlite
```

Now you have `.prisma/schema.prisma` in your project, make it match this config:

```[schema.prisma]
generator client {
provider = "prisma-client-js"
// preview feature enabling binding adapter
previewFeatures = ["driverAdapters"]
}

datasource db {
provider = "sqlite"
// url is required but won't be used
url = env("DATABASE_URL")
}
```

::note
No need to define `DATABASE_URL` in your `.env` file, it won't be used.
::
atinux marked this conversation as resolved.
Show resolved Hide resolved

### Create Models
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
### Create Models
### 3. Create Models


Your models are defined in the same file as the rest of Prisma config, `schema.prisma`. Let's add a model:

```[schema.prisma]
model Todos {
id Int @id @default(autoincrement())
title String
completed Boolean @default(false)
createdAt DateTime @default(now())
}
```

::callout{icon="i-ph-link" to="https://www.prisma.io/docs/orm/prisma-schema/data-model/models" external}
Help yourself defining your models and explore Prisma Models documentation
atinux marked this conversation as resolved.
Show resolved Hide resolved
::

### Generate Prisma Client
atinux marked this conversation as resolved.
Show resolved Hide resolved

Run this command to generate Prisma client:

```bash
npx prisma generate
```

::note
Don't forget to run this command each time you update your `schema.prisma` file.
::

### `usePrisma()`

Let's define our convenient server composable to finally be able to communicate with our database:

```ts[server/utils/prisma.ts]
import { PrismaD1 } from '@prisma/adapter-d1'
import { PrismaClient } from '@prisma/client'

export function usePrisma() {
const binding = process.env.DB || globalThis.__env__?.DB || globalThis.DB
const adapter = new PrismaD1(binding)
return new PrismaClient({ adapter })
}
```
atinux marked this conversation as resolved.
Show resolved Hide resolved

### Migrations
atinux marked this conversation as resolved.
Show resolved Hide resolved

::callout{icon="i-ph-link" to="https://developers.cloudflare.com/d1/tutorials/d1-and-prisma-orm#4-create-a-table-in-the-database" external}
This is not supported at the moment as Prisma Migrate does not support D1 yet.
::
atinux marked this conversation as resolved.
Show resolved Hide resolved

## Usage

### Select

```ts [server/api/todos/index.get.ts]
export default eventHandler(async () => {
const todos = await usePrisma().todos.findMany()
atinux marked this conversation as resolved.
Show resolved Hide resolved

return todos
})
```

### Insert

```ts [server/api/todos/index.post.ts]
export default eventHandler(async (event) => {
const { title } = await readBody(event)

const todo = await usePrisma().todos.create({
atinux marked this conversation as resolved.
Show resolved Hide resolved
data: {
title,
createdAt: new Date()
}
})

return todo
})
```

### Update

```ts [server/api/todos/[id].patch.ts]
export default eventHandler(async (event) => {
const { id } = getRouterParams(event)
const { completed } = await readBody(event)

const todo = await usePrisma().todos.update({
atinux marked this conversation as resolved.
Show resolved Hide resolved
where: {
id: Number(id)
},
data: {
completed
}
})

return todo
})
```

### Delete

```ts [server/api/todos/[id].delete.ts]
export default eventHandler(async (event) => {
const { id } = getRouterParams(event)

const deletedTodo = await usePrisma().todos.delete({
atinux marked this conversation as resolved.
Show resolved Hide resolved
where: {
id: Number(id)
}
})

if (!deletedTodo) {
throw createError({
statusCode: 404,
message: 'Todo not found'
})
}
return deletedTodo
})
```