前言:
今天大家对“jsrestapi”可能比较关注,看官们都想要剖析一些“jsrestapi”的相关资讯。那么小编也在网上汇集了一些关于“jsrestapi””的相关文章,希望我们能喜欢,兄弟们快快来了解一下吧!每日分享最新,最流行的软件开发知识与最新行业趋势,希望大家能够一键三连,多多支持,跪求关注,点赞,留言。
@头条创作挑战赛
了解如何使用 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启动应用程序并在.
有了这个,我们已经成功地使用 Prisma ORM 创建了一个 NestJS REST API。我们从 Prisma 的基础开始,按照自己的方式编写模式、生成迁移和客户端以与我们的数据库表进行交互。
这篇文章的代码可以在GitHub上找到,以防你想更仔细地研究它。
你是怎么找到这个帖子的?你已经开始在你的项目中使用Prisma ORM了吗?如果是,您如何在可用性方面找到它?还是您在项目中使用其他 ORM 框架?
我很想听听您对此事的看法。所以,请在评论区发表你的看法。如果这篇文章有帮助,请喜欢并分享它。这将有助于帖子覆盖更多人。
标签: #jsrestapi