Skip to content

mettbox/sveltekit-prisma

Repository files navigation

SvelteKit and Prisma

Learn how to use Prisma to persist data in your sveltekit application.

We are going to start with a default SvelteKit application, install and configure Prisma before we will use the PrismaClient to perform CRUD actions with a MySQL database.

SvelteKit demo app

$ npm init svelte@next myapp
✔ Which Svelte app template? › SvelteKit demo app
✔ Use TypeScript? › Yes
✔ Add ESLint for code linting? › Yes
✔ Add Prettier for code formatting? › Yes

$ cd myapp
$ yarn
$ git init && git add -A && git commit -m "Initial commit"

Start a development server:

yarn run dev

# or start the server and open the app in a new browser tab
yarn run dev -- --open

Look around in the SvelteKit demo app. Then you'll understand better what will be adjusted right away and what can be used further.

Install Prisma

$ yarn add --dev prisma
$ npx prisma init

Set the DATABASE_URL in the .env file.

# ./.env
DATABASE_URL="mysql://janedoe:mypassword@localhost:3306/mydb"

My database is located at Uberspace and is remotely accessible only through an SSH tunnel.

ssh -L 3306:127.0.0.1:3306 myuser@xy.uberspace.de

Set the provider of the datasource:

# ./prisma/schema.prisma
datasource db {
  provider = "mysql"
  url = env("DATABASE_URL")
}

Generate the Prisma Client:

$ npx prisma generate

We now store the generated code snippet in the lib folder to make the Prisma client available for our Todo API.

# src/lib/prisma.ts

import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()
export default PrismaClient

Create the database and tables

Define the Todo model:

# ./prisma/schema.prisma
model Todo {
  uid        String  @id @default(cuid())
  created_at DateTime
  text       String
  done       Boolean
}

Push the Prisma schema state to the database. You can then start querying.

$ npx prisma db push

Implement CRUD actions

The SvelteKit demo app encapsulates all API features in the src/routes/todos/_api.ts file. We are going to modify the file to deal with CRUD using the PrismaClient.

// src/routes/todos/_api.ts

import type { Locals, Todo } from '$lib/types'
import PrismaClient from '$lib/prisma'

const prisma = new PrismaClient()

export async function api(method: string, resource: string, data?: Record<string, unknown>) {
  let body = {}
  let status = 500

  switch (method.toUpperCase()) {
    case 'DELETE':
      await prisma.todo.delete({
        where: {
          uid: resource.split('/').pop()
        }
      })
      status = 200
      break
    case 'GET':
      body = await prisma.todo.findMany()
      status = 200
      break
    case 'PATCH':
      body = await prisma.todo.update({
        data: {
          done: data.done,
          text: data.text
        },
        where: {
          uid: resource.split('/').pop()
        }
      })
      status = 200
      break
    case 'POST':
      body = await prisma.todo.create({
        data: {
          created_at: new Date(),
          done: false,
          text: data.text
        }
      })
      status = 201
      break
  }

  // If the request came from a <form> submission, the browser's default
  // behaviour is to show the URL corresponding to the form's "action"
  // attribute. In those cases, we want to redirect them back to the
  // /todos page
  if (method.toUpperCase() !== 'GET') {
    return {
      status: 303,
      headers: {
        location: '/todos'
      }
    }
  }

  return { status, body }
}

The API output has now changed a bit compared to the fetch request of the original demo app. The following code block must therefore be adjusted:

// src/routes/todos/index.ts
...
if (response.status === 200) {
  return {
    body: {
      todos: await response.json() // <- replace this
      todos: await response.body // <- with this
    }
  };
}

Building

Before you can create a production version of your SvelteKit app, you need to adapt it for your deployment target. See Adapters.

Let's try it with a simple node server:

$ yarn add --dev @sveltejs/adapter-node@next
// svelte.config.js

import adapter from '@sveltejs/adapter-auto'  // <- replace this
import adapter from '@sveltejs/adapter-node'// <- with this

To create a production version of your app:

yarn run build

You can preview the production build:

$ yarn run preview

Run production build:

$ node build

Done :-)

About

SvelteKit Demo App using Prisma/ MySQL to persist the Todo list

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published