Koa + Prisma Quick Start

Master Koa + Prisma in 10 minutes to implement database CRUD

foreword

Prisma is the so-called next-generation ORM tool, which is also implemented based on TypeScript, but it brings strong type safety.

This article uses Koa.js to build a simple web service and cooperates with MySQL database to demonstrate how to add, delete, modify and query data through Prisma.

Prisma

Prisma is a so-called next-generation ORM tool. The following is the Prisma Chinese website , which can be said to be a very good Chinese website among technical websites:

image-20230509200931239

Prisma is an open source database toolchain project, not just a simple ORM tool. The databases it supports include PostgreSQL, MySQL, MongoDB, SQL Server, and SQLite. This article uses MySQL for demonstration.

In terms of usage, it is a little cumbersome for those who are exposed to it for the first time. I have summarized the following processes:

  • install dependencies
  • Initialize the Prisma project
  • Design Prisma Schema (database information and models)
  • sync to database
  • Generate Prisma Client
  • Use Prisma Client to complete CRUD

Let's create a development environment first, and then go back and continue to introduce Prisma.

Initialize the environment

Use Koa to quickly build a web service, first create a directory and install dependencies:

$ mkdir koa-prisma
$ cd koa-prisma
$ pnpm init

# 安装 Koa 依赖
$ pnpm add koa @koa/router koa-bodyparser
  • @koa/router: Routing middleware, easy to integrate routing functions
  • koa-bodyparser: parse the request body data and put it on the ctx.request.body object

Then create a new one index.jsto complete a simple web service:

const Koa = require('koa')
const Router = require('@koa/router')
const bodyParser = require('koa-bodyparser')

const app = new Koa()

// 实例化路由器,并设置公共路由前缀 /users
const router = new Router({
    
    
  prefix: '/users'
})

app.use(bodyParser())

// 查询用户列表
router.get('/', async ctx => {
    
    
 
})

// 查询单个用户
router.get('/:id', async ctx => {
    
    
 
})

// 创建用户
router.post('/', async ctx => {
    
    

})

// 更新用户
router.patch('/:id', async ctx => {
    
    

})

// 删除用户
router.delete('/:id', async ctx => {
    
    

})

// 注册路由中间件
app.use(router.routes()).use(router.allowedMethods())

app.listen(3000, () => {
    
    
  console.log('服务器运行在 3000 端口')
})

In the above code, five routing methods are defined, corresponding to the query, insert, update and delete operations of the database. After completing the initialization of Prisma later and introducing Prisma Client, these interfaces can be realized.

Then use nodemonthe command to start the service, it is best to install this module globally for easy use:

$ nodemon src/index.js

Prisma CLI

First install the two dependent modules of Prisma:

$ pnpm add -D prisma 
$ pnpm add @prisma/client

The first prisma installed is a CLI command, which is mainly used to call various functions of Prisma, including database migration, creating Prisma Client and so on.

Execute the following command to see how to use prisma:

$ npx prisma --help

image-20230509194858894

As you can see, prisma provides 7 commands:

Order illustrate
init Initialize Prisma in the application
generate Mainly used to generate Prisma Client
db Manage the schema and lifecycle of your database
migrate migrate database
studio Start a web-side workbench to manage data
validate Check Prisma's schema files for correct syntax
format Format the schema file of Prisma, the default is prisma/schema.prisma

And it also gives examples, we mainly use three of them here, and you can use the rest to see the effect by yourself:

image-20230509195654406

Initialize Prisma

Execute the following command to complete the initialization:

$ npx prisma init

image-20230509220945387

.envThe effect of this command is to create a file and a directory in the directory where the command is located, that is, the current root directory prisma, and create a file in this directory schema.prisma, as follows:

image-20230509195929494

.envEveryone is familiar with the file, which is a file that places environment variables. The environment variables in it are usually some configuration information.

prismaThe directory is used to store files related to Prisma. Currently there is only one schema.prismafile, which is the Prisma schema file mentioned above. We will define the connection information and model of the database in this file.

Design Prisma Schema

schema.prismais the main configuration file using Primsa, called the Prisma schema file, which contains three basic structures:

  • data source

  • Builder

  • Data Model Definition

Install the VSC plugin

PrismaBefore editing the pattern file, install the plugin in VS Code , which .prismaprovides code highlighting, formatting, auto-completion, jump definition and inspection functions for the file. Without the support of this plugin, the schema file is just plain text.

image-20230507161551169

set builder

Use to generatedefine the generator, and declare it through the provider attribute prisma-client-js(currently only supports this one). When the command is executed prisma generate, the Prisma Client will be generated, and it will be used to complete the addition, deletion, modification and query of data.

generator client {
    
    
  provider = "prisma-client-js"
}

set data source

Use datasourceis to define the data source, some information needed to set up the database Prisma is connected to. providerIs the type of database to connect to, the default is postgresql, we changed to mysql to be used. urlIt is the database URL. Usually, in order to keep the configuration separate, it will be defined separately in an environment variable file, which is the .envfile automatically generated by prisma cli. Through env()the function, the variables in this file will be read.

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

Take a look at .envthe file, the default connection is Postgresql:

DATABASE_URL=postgresql://johndoe:mypassword@localhost:5432/mydb?schema=public

This is the composition of a database connection URL:

Structure of the MySQL connection URL

The following are required fields:

name Placeholder describe
Host HOST Database IP or domain name, for examplelocalhost
Port PORT database port, eg3306
User USER database username, egroot
Password PASSWORD database password
Database DATABASE database name, such asmydb

According to this instruction, define our own MySQL URL:

DATABASE_URL="mysql://root:root123@localhost:3306/prisma"

Define the User model

As an ORM tool, the model must be indispensable. Prisma's model mainly has the following functions:

  • Entities that make up the application domain
  • Tables mapped to databases (relational databases, such as PostgreSQL) or collections (MongoDB)
  • Forms the basis for queries in the Prisma Client API
  • When using TypeScript, Prisma Client provides type definitions for models and their variants , ensuring type safety for database access

These Prisma built-in utility functions of the form @id(), are used when defining the model. @default()For example, @id()it is used to declare the primary key and @default()to set the default value. The naming is very semantic. It is basically some keywords in SQL, which is very easy to understand.

Here is the definition of a User model:

model User {
    
    
  id          Int      @id @default(autoincrement())
  name        String   
  email       String   @unique
  password    String
  createdTime DateTime @default(now()) @map("created_time")
  updatedTime DateTime @updatedAt @map("updated_time")

  @@map("user")
}

A few points of information that need clarification:

1. The name of the model is the name of the created data table by default. Here is the uppercase User, then the data table name is also the uppercase User. You can use to @@map()set the mapped table name and change it to lowercase user.

2. The records of each model are uniquely identifiable, that is, there must be a primary key, which can be declared using @id.

3. The type of the field, such as Int and String, will be converted to the corresponding type of the database through Prisma, that is, int and varchar.

4. @uniqueIt is a unique value constraint, so the value of the email field in the generated user table cannot be repeated.

5. Like the creation time and update time, in order to comply with the naming conventions in JS and TS, the camel case is used. In order to comply with the database naming convention, remapping is used later @map()to name underscores.

sync database

Synchronize the Prisma model to the database. For a new project like ours, an empty project, you can use the following command:

$ npx prisma db push

If it is a project that already has data, you cannot use this command and use prisma migratemigration instead. This article does not involve.

image-20230509213137705

It will create the schema of the database, and use the Prisma schema to synchronize the database, and will "secretly" execute the following prisma generatecommand to generate the Prisma Client.

prismaCome to the database, refresh it, the database and a table have been created user:

image-20230509213437412

Generate Prisma client

It has already been executed when synchronizing the database earlier prisma generate. So now there is no need to execute it again, but once the Prisma Schema file changes, such as modifying the model, you need to execute this command again to regenerate the Prisma Client.

generateThe flow of command execution is:

img

CRUD addition, deletion, modification and query

Initialize Prisma Client

With Prisma Client, you can use it to perform CRUD operations. initialization:

const {
    
     PrismaClient } = require('@prisma/client')

const prisma = new PrismaClient()

Prisma, an instance of Prisma Client, has various types and can be used in the following ways prisma.模型.CRUD方法:

image-20230509214952783

image-20230509215012306

Let's first introduce a few commonly used APIs:

  • findMany: query multiple records
  • findUnique: query a single record
  • create: create a record
  • update: update record
  • delete: delete the record

Use these APIs to operate the database in the routing method to complete the development of the interface.

Query user list

findMany does not pass in parameters, which means to query all records of the entire user table, and it returns an array, which is a collection of instances of the User model:

router.get('/', async ctx => {
    
    
  const users = await prisma.user.findMany()

  ctx.body = users
})

query a single user

In findUniquethe method, whereset the query condition, that is, query a user record according to the specified ID. This method returns only one record, which is Useran instance of the model:

// 查询单个用户
router.get('/:id', async ctx => {
    
    
  const id = parseInt(ctx.params.id)
  const user = await prisma.user.findUnique({
    
    
    where: {
    
     id }
  })

  ctx.body = user
})

One thing to note is that ctx.params.idthe obtained from idis a string type, which needs to be converted to an integer type before querying.

create user

Use createto insert data, just assign the data parsed from the request body, that is, Useran object describing the model, to the data attribute:

router.post('/', async ctx => {
    
    
  const user = ctx.request.body
  const newUser = await prisma.user.create({
    
    
    data: user
  })

  ctx.body = newUser
})

update user

Use the method to query a user updateby setting query conditions, and then assign the data to be updated to data to complete the update:where

router.patch('/:id', async ctx => {
    
    
  const id = parseInt(ctx.params.id)
  const updateUser = ctx.request.body

  const user = await prisma.user.update({
    
    
    where: {
    
    
      id
    },
    data: updateUser
  })

  ctx.body = user
})

delete users

Use deletethe method to directly set the query conditions for deleting records through where:

router.delete('/:id', async ctx => {
    
    
  const id = parseInt(ctx.params.id)
  const user = await prisma.user.delete({
    
    
    where: {
    
    
      id
    }
  })

  ctx.body = user
})

Note: When using update and delete, be sure to set where, otherwise all records in the data table will be updated or deleted, which is very dangerous.

test

Create user:

image-20230509215720849

Query user list:

image-20230509215836753

Update user:

image-20230509215918093

delete users:

image-20230509215939149

Summarize

The full code is here .

This article demonstrates the basic use of Prisma in Koa through an example of user addition, deletion, modification and query. Here is a summary:

  1. install dependencies
  2. Initialize Prisma
  3. Setting Prisma Schema
  4. sync database
  5. Create Prisma Client
  6. Implementing CRUD with Prisma Client

Prisma also has many excellent features. This article introduces the most basic use, adding, deleting, modifying and checking a single table. I recommend you to read the Chinese documentation site to learn more about Prisma.

Thanks for reading!

Guess you like

Origin blog.csdn.net/Old_Soldier/article/details/132524562