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

使用 Prisma ORM 构建 NestJS Rest API

ccwgpt 2024-09-27 07:19 38 浏览 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 框架?
我很想听听您对此事的看法。所以,请在评论区发表你的看法。如果这篇文章有帮助,请喜欢并分享它。这将有助于帖子覆盖更多人。

相关推荐

Python+ Appium:Android手机连接与操作详解(附源码)

在移动端自动化测试领域,Appium一直是最热门的开源工具之一。今天这篇文章,我们聚焦Android端自动化测试的完整流程,从环境配置到代码实战,一步一步带你掌握用Python控制Android...

全平台开源即时通讯IM框架MobileIMSDK开发指南,支持鸿蒙NEXT

写在前面在着手基于MobileIMSDK开发自已的即时通讯应用前,建议以Demo工程为脚手架,快速上手MobileIMSDK!Demo工程主要用于演示SDK的API调用等,它位于SDK完整下载包的如下...

移动开发(一):使用.NET MAUI开发第一个安卓APP

对于工作多年的C#程序员来说,近来想尝试开发一款安卓APP,考虑了很久最终选择使用.NETMAUI这个微软官方的框架来尝试体验开发安卓APP,毕竟是使用VisualStudio开发工具,使用起来也...

在安卓系统上开发一款软件详细的流程

安卓app软件开发流程是一个系统而复杂的过程,涉及多个阶段和环节。以下是一个典型的安卓软件开发流程概述:1.需求分析目的:了解用户需求,确定APP的目标、功能、特性和预期效果。活动:开发团队与客户进...

ArkUI-X在Android上使用Fragment开发指南

本文介绍将ArkUI框架的UIAbility跨平台部署至Android平台Fragment的使用说明,实现Android原生Fragment和ArkUI跨平台Fragment的混合开发,方便开发者灵活...

Web3开发者必须要知道的6个框架与开发工具

在Web3领域,随着去中心化应用和区块链的兴起,开发者们需要掌握适用于这一新兴技术的框架与开发工具。这些工具和框架能够提供简化开发流程、增强安全性以及提供更好的用户体验。1.Truffle:Truff...

Python开发web指南之创建你的RESTful APP

上回我们说到了:PythonFlask开发web指南:创建RESTAPI。我们知道了Flask是一个web轻量级框架,可以在上面做一些扩展,我们还用Flask创建了API,也说到了...

python的web开发框架有哪些(python主流web框架)

  python在web开发方面有着广泛的应用。鉴于各种各样的框架,对于开发者来说如何选择将成为一个问题。为此,我特此对比较常见的几种框架从性能、使用感受以及应用情况进行一个粗略的分析。  1Dja...

Qwik:革新Web开发的新框架(webview开源框架)

听说关注我的人,都实现了财富自由!你还在等什么?赶紧加入我们,一起走向人生巅峰!Qwik:革新Web开发的新框架Qwik橫空出世:一场颠覆前端格局的革命?是炒作还是未来?前端框架的更新迭代速度,如同...

Python中Web开发框架有哪些?(python主流web框架)

Python为Web开发提供了许多优秀的框架。以下是一些流行的PythonWeb框架:1.Django:一个高级的Web框架,旨在快速开发干净、实用的Web应用。Django遵...

WPF 工业自动化数据管控框架,支持热拔插 DLL与多语言实现

前言工业自动化开发中,设备数据的采集、处理与管理成为提升生产效率和实现智能制造的关键环节。为了简化开发流程、提高系统的灵活性与可维护性,StarRyEdgeFramework应运而生。该框架专注...

[汇川PLC] 汇川IFA程序框架06-建立气缸控制FB块

前言:汇川的iFA要跟西门子对标啦,这可是新的选择!就在2月14日,汇川刚发布的iFA平台,一眼就能看出来是对标西门子的全集成自动化平台博途(TIAPortal)。这个平台能在同一个...

微软发布.NET 10首个预览版:JIT编译器再进化、跨平台开发更流畅

IT之家2月26日消息,微软.NET团队昨日(2月25日)发布博文,宣布推出.NET10首个预览版更新,重点改进.NETRuntime、SDK、libraries、C#、AS...

大模型部署革命:GGUF量化+vLLM推理的极致性能调优方案

本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在官网-聚客AI学院大模型应用开发微调项目实践课程学习平台一、模型微调核心概念与技术演进1.1微调的本质与优势数学表达:1....

拓扑学到底在研究什么?(拓扑学到底在研究什么问题)

拓扑是“不量尺寸的几何学”,那么它的核心内容,主要方法是什么?如果你问罗巴切夫斯基,他会说“附贴性是物体的一个特殊的属性。如果我们把这个性质掌握,而把物体其他的一切属性,不问是本质的或偶然出现的,均不...

取消回复欢迎 发表评论: