百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

使用 Prisma ORM 构建 NestJS Rest API

ccwgpt 2024-09-27 07:19 25 浏览 0 评论

每日分享最新,最流行的软件开发知识与最新行业趋势,希望大家能够一键三连,多多支持,跪求关注,点赞,留言。

@头条创作挑战赛

了解如何使用 Prisma ORM 构建 NestJS REST API。

NestJS 是一个用于构建后端应用程序的非常可靠的框架。
在这篇文章中,我们将利用我们的 NestJS 知识并将其与 Prisma 结合起来构建一个 RESTful API。这篇文章将有一堆代码,你可以从最后的 Github 链接中获得,或者你也可以一起编写代码。
如果你是 NestJS 的新手,你可以从这篇文章开始,从 NestJS 开始。
什么是Prisma?
Prisma 是下一代对象关系映射器(ORM)。我们可以将它与 Typescript 以及 Javascript 一起使用。它采用了与传统 ORM 有所不同的方法。您可以查看Prisma 的官方网站以获取更多信息。
Prisma 没有使用类,而是使用一种特殊的模式定义语言。
基本上,开发人员使用这种模式定义语言来描述他们的模式。Prisma 运行模式并根据所选数据库编写适当的迁移。它还生成与数据库交互的类型安全代码。
换句话说,Prisma 提供了编写普通 SQL 查询或使用其他 ORM(例如 TypeORM 或 Sequelize)的替代方法。它可以与各种数据库一起使用,例如 PostgreSQL、MySQL、SQLite 甚至 MongoDB。
Prisma 由两个主要部分组成:
Prisma Migrate – 这是 Prisma 提供的迁移工具。它帮助我们保持我们的数据库模式与 Prisma 模式同步。对于我们的架构的每次更改,Prisma Migrate都会生成一个迁移文件。通过这种方式,它还 有助于维护我们的架构可能发生的所有更改的历史记录。
Prisma Client – 这是自动生成的查询生成器。Prisma Client充当我们的应用程序代码和数据库之间的桥梁。它还提供类型安全。
我们将使用 Prisma Migrate 和 Prisma Client 来构建我们的应用程序。
Prisma ORM 有多好?
虽然这可能是一个主观问题,但Prisma 旨在让开发人员更容易处理数据库查询。
任何开发人员都知道,对于大多数应用程序来说,与数据库交互以管理数据是绝对必要的。这种交互可以使用原始查询或ORM 框架(例如 TypeORM)进行。虽然原始查询或查询构建器提供了更多控制,但它们降低了开发人员的整体生产力。
另一方面,ORM 框架通过将数据库模型定义为类来抽象 SQL。这提高了生产力,但大大减少了开发人员的控制。它还导致对象阻抗不匹配。
对象阻抗不匹配是当面向对象的编程语言与关系数据库交互时出现的概念问题。在关系数据库中,数据是标准化的,不同实体之间的链接是通过外键来实现的。但是,对象使用嵌套结构建立相同的关系。编写应用程序代码的开发人员习惯于思考对象及其结构。这在处理关系数据库时会导致不匹配。
Prisma 试图通过提高开发人员的工作效率同时给予他们更多的控制权来解决围绕对象关系映射的问题。
Prisma 如何实现这一点的一些重要方法如下:
它允许开发人员根据对象进行思考。
它有助于避免复杂的模型对象
它有助于使用模式文件 为数据库和应用程序维护单一的事实来源
便于编写 类型安全查询以在编译时捕获错误
更少的样板代码。开发人员可以简单地定义他们的模式,而不用担心特定的 ORM 框架。
设置 NestJS Prisma 项目
有了对 Prisma 的基本了解,我们现在可以开始构建我们的NestJS Prisma REST API。
作为第一步,我们使用 Nest CLI 创建一个新的 NestJS 项目。下面的命令创建一个新的工作 NestJS 项目。

$ nest new nestjs-prisma-demo-app
$ cd nestjs-prisma-demo-app


在下一步中,我们安装Prisma。

$ npm install prisma --save-dev

请注意,这只是一个开发依赖项。
我们将使用Prisma CLI与 Prisma 一起工作。要调用 CLI,我们使用npx如下。

$ npx prisma


激活 Prisma 后,我们将创建初始 Prisma 设置。

$ npx prisma init


此命令在我们的项目目录中创建一个名为的新目录prisma和一个配置文件。
schema.prisma– 从 Prisma 的角度来看,这是最重要的文件。它将出现在prisma目录中。它指定数据库连接,还包含数据库模式。您可以将其视为我们应用程序的核心。
.env– 这就像一个环境配置文件。它存储数据库主机名和凭据。如果它包含数据库凭据,请注意不要将此文件提交到源存储库。
Prisma 数据库连接设置
对于我们的演示NestJS Prisma 应用程序,我们将使用SQLite作为我们的数据库。这是一个易于使用的数据库选项,因为 SQLite 将数据存储在文件中。因此,我们不必设置数据库服务器。
要配置我们的数据库连接,我们必须在schema.prisma文件中进行更改。
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "sqlite"
url = env("DATABASE_URL")
}
基本上,我们必须将datasource DB部分中的提供者更改为sqlite。默认情况下,它使用Postgres,但您也可以使用其他数据库解决方案。
第二个更改是在.env文件中。

DATABASE_URL="file:./test.db"


在这里,我们指定数据库文件的路径。文件名为test.db. 你可以随意命名它。
Prisma 迁移命令
现在,我们准备在SQLite数据库中创建表。
为此,我们将首先编写我们的模式。如前所述,模式是在schema.prisma 我们刚才看到的文件中定义的。
我们将更新相同的文件,如下所示:
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "sqlite"
url = env("DATABASE_URL")
}
model Book {
id Int @default(autoincrement()) @id
title String
author String
publishYear Int
}
如您所见,我们使用模式定义语言创建了一个名为Book的模型。它有一些基本属性,例如title,author和publishYear. 是id一个整数并设置为自动递增。
这个模式是我们的应用程序和数据库的唯一真实来源。无需像 TypeORM 等其他 ORM 那样编写任何其他类。在以后的帖子中对此进行更多介绍。
我们现在将使用Prisma Migrate生成迁移文件。

$ npx prisma migrate dev --name init


基本上,此命令会生成 SQL 文件并在配置的数据库上运行它们。您应该能够prisma/migrations在项目的目录中找到以下 SQL 文件。

CREATE TABLE "Book" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"title" TEXT NOT NULL,
"author" TEXT NOT NULL,
"publishYear" INTEGER NOT NULL
);


test.db此外,将自动创建数据库文件。
安装和生成 Prisma 客户端
我们的数据库现已准备就绪。但是,我们仍然没有办法从我们的应用程序与数据库进行交互。
这就是Prisma Client出现的地方。
但是什么是 Prisma 客户端?
Prisma Client 是一个类型安全的数据库客户端,用于与我们的数据库进行交互。它是使用我们文件中的模型定义生成的。prisma.schema换句话说,客户端公开了特定于我们模型的 CRUD 操作。
我们可以使用以下命令安装 Prisma Client。

$ npm install @prisma/client

在后台,安装步骤也执行prisma generate命令。如果我们对架构进行更改(例如添加字段或新模型),我们可以简单地调用prisma generate命令来相应地更新我们的Prisma 客户端。
安装成功后,Prisma 客户端库node_modules/@prisma/client 会相应更新。
创建数据库服务
在我们的核心应用程序中直接使用Prisma Client API并不是一个好习惯。因此,我们将在另一个服务中抽象出 Prisma Client API。
请参阅文件中的以下代码db.service.ts。
import { INestApplication, Injectable, OnModuleInit } from "@nestjs/common";
import { PrismaClient } from "@prisma/client";
@Injectable()
export class DBService extends PrismaClient implements OnModuleInit {
async onModuleInit() {
await this.$connect();
}
async enableShutdownHooks(app: INestApplication) {
this.$on('beforeExit', async () => {
await app.close();
})
}
}
基本上,这是我们应用程序的数据库服务,它扩展了我们在上一步中生成的PrismaClient。它实现了接口OnModuleInit。如果我们不使用OnModuleInit,Prisma 会懒惰地连接到数据库。
Prisma 也有自己的关闭机制,它会破坏数据库连接。因此,我们enableShutdownHooks()在 e 中实现该方法,并在文件DBServic中调用它。main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { DBService } from './db.service';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const dbService: DBService = app.get(DBService);
dbService.enableShutdownHooks(app)
await app.listen(3000);
}
bootstrap();
创建应用服务
现在我们的数据库服务已经设置好了,我们可以创建实际的应用程序服务了。该服务公开了从数据库中读取、创建、更新和删除书籍的方法。
从名为的文件中查看以下代码book.service.ts:
import { Injectable } from "@nestjs/common";
import { Book, Prisma } from "@prisma/client";
import { DBService } from "./db.service";
@Injectable()
export class BookService {
constructor(private dbService: DBService) {}
async getBook(id: Prisma.BookWhereUniqueInput): Promise<Book | null> {
return this.dbService.book.findUnique({
where: id
})
}
async createBook(data: Prisma.BookCreateInput): Promise<Book> {
return this.dbService.book.create({
data,
})
}
async updateBook(params: {
where: Prisma.BookWhereUniqueInput;
data: Prisma.BookUpdateInput;
}): Promise<Book> {
const { where, data } = params;
return this.dbService.book.update({
data,
where,
});
}
async deleteBook(where: Prisma.BookWhereUniqueInput): Promise<Book> {
return this.dbService.book.delete({
where,
});
}
}
这是一个标准的NestJS 服务,我们在其中注入DBService的一个实例。但是,需要注意的重要一点是使用Prisma Client 生成的 类型,例如BookCreateInput、BookUpdateInput、Book等,以确保我们服务的方法正确键入。无需创建任何额外的 DTO 或接口来支持类型安全。
创建 REST API 控制器
最后,我们可以创建一个 NestJS 控制器来实现 REST API 端点。
从名为的文件中查看以下代码book.controller.ts.
import { Body, Controller, Delete, Get, Param, Post, Put } from "@nestjs/common";
import { Book } from "@prisma/client";
import { BookService } from "./book.service";
@Controller()
export class BookController {
constructor(
private readonly bookService: BookService
) {}
@Get('books/:id')
async getBookById(@Param('id') id: string): Promise<Book> {
return this.bookService.getBook({id: Number(id)});
}
@Post('books')
async createBook(@Body() bookData: {title: string, author: string, publishYear: Number}): Promise<Book> {
const { title, author } = bookData;
const publishYear = Number(bookData.publishYear);
return this.bookService.createBook({
title,
author,
publishYear
})
}
@Put('books/:id')
async updateBook(@Param('id') id: string, @Body() bookData: {title: string, author: string, publishYear: Number}): Promise<Book> {
const { title, author } = bookData;
const publishYear = Number(bookData.publishYear);
return this.bookService.updateBook({
where: {id: Number(id)},
data: {
title,
author,
publishYear
}
})
}
@Delete('books/:id')
async deleteBook(@Param('id') id: string): Promise<Book> {
return this.bookService.deleteBook({
id: Number(id)
})
}
}
在这里,我们也使用Prisma ClientBook生成的类型来实现类型安全。
作为最后一步,我们在 App Module(文件)中配置控制器和服务app.module.ts,以便 NestJS 在应用程序启动期间可以发现它们。
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { BookController } from './book.controller';
import { BookService } from './book.service';
import { DBService } from './db.service';
@Module({
imports: [],
controllers: [AppController, BookController],
providers: [AppService, BookService, DBService],
})
export class AppModule {}
我们的应用程序现已准备就绪。我们可以使用npm run start启动应用程序并在http://localhost:3000/books.
有了这个,我们已经成功地使用 Prisma ORM 创建了一个 NestJS REST API。我们从 Prisma 的基础开始,按照自己的方式编写模式、生成迁移和客户端以与我们的数据库表进行交互。
这篇文章的代码可以在GitHub上找到,以防你想更仔细地研究它。
你是怎么找到这个帖子的?你已经开始在你的项目中使用Prisma ORM了吗?如果是,您如何在可用性方面找到它?还是您在项目中使用其他 ORM 框架?
我很想听听您对此事的看法。所以,请在评论区发表你的看法。如果这篇文章有帮助,请喜欢并分享它。这将有助于帖子覆盖更多人。

相关推荐

机器学习框架TensorFlow入门(tensorflow框架详解)

ensorFlow是一个广泛使用的开源机器学习框架,由GoogleBrain团队开发。它支持广泛的机器学习和深度学习任务,并且可以在CPU和GPU上运行。下面是一个使用TensorF...

合肥高新区企业本源发布量子机器学习框架VQNet 开辟量子机器学习的新领域

近日,高新区企业合肥本源量子计算科技有限责任公司通过研究混合实现变分量子算法和经典机器学习框架的可能性,全新开发了量子机器学习框架VQNet,可满足构建所有类型的量子机器学习算法,实现量子-经典混合任...

如何使用 TensorFlow 构建机器学习模型

在这篇文章中,我将逐步讲解如何使用TensorFlow创建一个简单的机器学习模型。TensorFlow是一个由谷歌开发的库,并在2015年开源,它能使构建和训练机器学习模型变得简单。我们接下...

机器学习框架底层揭秘:PyTorch、TensorFlow 如何高效“跑模型”

在使用PyTorch或TensorFlow时,你是否想过:这些深度学习框架底层到底是怎么运行的?为什么我们一行.backward()就能自动计算梯度?本篇将用最简单的语言,拆解几个关键概念...

2 个月的面试亲身经历告诉大家,如何进入 BAT 等大厂?

这篇文章主要是从项目来讲的,所以,从以下几个方面展开。怎么介绍项目?怎么介绍项目难点与亮点?你负责的模块?怎么让面试官满意?怎么介绍项目?我在刚刚开始面试的时候,也遇到了这个问题,也是我第一个思考的问...

基于SpringBoot 的CMS系统,拿去开发企业官网真香(附源码)

前言推荐这个项目是因为使用手册部署手册非常完善,项目也有开发教程视频对小白非常贴心,接私活可以直接拿去二开非常舒服开源说明系统100%开源模块化开发模式,铭飞所开发的模块都发布到了maven中央库。可...

【网络安全】关于Apache Shiro权限绕过高危漏洞的 预警通报

近日,国家信息安全漏洞共享平台(CNVD)公布了深信服终端检测平台(EDR)远程命令执行高危漏洞,攻击者利用该漏洞可远程执行系统命令,获得目标服务器的权限。一、漏洞情况ApacheShiro是一个强...

开发企业官网就用这个基于SpringBoot的CMS系统,真香

前言推荐这个项目是因为使用手册部署手册非常完善,项目也有开发教程视频对小白非常贴心,接私活可以直接拿去二开非常舒服。开源说明系统100%开源模块化开发模式,铭飞所开发的模块都发布到了maven中央库。...

这款基于SpringBoot 的CMS系统,开发企业官网确实香(附源码)

前言推荐这个项目是因为使用手册部署手册非常完善,项目也有开发教程视频对小白非常贴心,接私活可以直接拿去二开非常舒服开源说明系统100%开源模块化开发模式,铭飞所开发的模块都发布到了maven中央库。可...

【推荐】一款基于BPM和代码生成器的 AI 低代码开源平台

如果您对源码&技术感兴趣,请点赞+收藏+转发+关注,大家的支持是我分享最大的动力!!!项目介绍JeecgBoot是一款基于BPM和代码生成器的AI低代码平台,专为Java企业级Web应用而生。它采...

云安全日报200819:Apache发现重要漏洞 可窃取信息 控制系统 需要尽快升级

ApacheHTTPServer(简称Apache)是Apache软件基金会的一个开放源码的网页服务器,可以在大多数计算机操作系统中运行,由于其多平台和安全性被广泛使用,是最流行的Web服务器端软...

基于jeecgboot框架的cloud商城源码分享,兼容单体和微服务模式

3年时间里,随着关注java单商户商城系统的朋友越来越多,对cloud版本的商城呼声也越来越高。因此今年立项了cloud版本的开发,目前已发gitee开源,目前也基本测试完毕,欢迎大家体验以及提出宝贵...

SpringBoot + Mybatis + Shiro + mysql + redis智能平台源码分享

后端技术栈基于SpringBoot+Mybatis+Shiro+mysql+redis构建的智慧云智能教育平台基于数据驱动视图的理念封装element-ui,即使没有vue的使...

我敢保证,全网没有再比这更详细的Java知识点总结了,送你啊

接下来你看到的将是全网最详细的Java知识点总结,全文分为三大部分:Java基础、Java框架、Java+云数据小编将为大家仔细讲解每大部分里面的详细知识点,别眨眼,从小白到大佬、零基础到精通,你绝...

基于Spring+SpringMVC+Mybatis分布式敏捷开发系统架构(附源码)

前言zheng项目不仅仅是一个开发架构,而是努力打造一套从前端模板-基础框架-分布式架构-开源项目-持续集成-自动化部署-系统监测-无缝升级的全方位J2EE企业级开发解...

取消回复欢迎 发表评论: