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:
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.js
to 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 nodemon
the 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
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:
Initialize Prisma
Execute the following command to complete the initialization:
$ npx prisma init
.env
The 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:
.env
Everyone is familiar with the file, which is a file that places environment variables. The environment variables in it are usually some configuration information.
prisma
The directory is used to store files related to Prisma. Currently there is only one schema.prisma
file, 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.prisma
is 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
Prisma
Before editing the pattern file, install the plugin in VS Code , which .prisma
provides 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.
set builder
Use to generate
define 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 datasource
is to define the data source, some information needed to set up the database Prisma is connected to. provider
Is the type of database to connect to, the default is postgresql, we changed to mysql to be used. url
It 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 .env
file 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 .env
the 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:
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. @unique
It 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 migrate
migration instead. This article does not involve.
It will create the schema of the database, and use the Prisma schema to synchronize the database, and will "secretly" execute the following prisma generate
command to generate the Prisma Client.
prisma
Come to the database, refresh it, the database and a table have been created user
:
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.
generate
The flow of command execution is:
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方法
:
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 findUnique
the method, where
set the query condition, that is, query a user record according to the specified ID. This method returns only one record, which is User
an 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.id
the obtained from id
is a string type, which needs to be converted to an integer type before querying.
create user
Use create
to insert data, just assign the data parsed from the request body, that is, User
an 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 update
by 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 delete
the 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:
Query user list:
Update user:
delete users:
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:
- install dependencies
- Initialize Prisma
- Setting Prisma Schema
- sync database
- Create Prisma Client
- 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!