如何建立一个使用MongoDB的Prisma客户服务器

487 阅读12分钟

如何建立一个使用MongoDB的Prisma客户端服务器

Prisma是一个ORM,它允许你编写类型安全的数据库模式。它支持主要的数据库,如MySQL、PostgreSQL、MongoDB、MariaDB、Azure SQL、Microsoft SQL Server、AWS Aurora和AWS Aurora Serverless。

这意味着你可以轻松地挑选适合你的应用程序的代码结构的数据库,甚至在数据库之间切换,而不需要改变你的应用程序的代码结构。

Prisma还支持不同的语言。在写文章的时候,Prisma支持三种主要语言。它们是TypeScript、JavaScript和Go。

在本指南中,我们学习如何用MongoDB设置Prisma客户端Node.js服务器。

前提条件

要跟上本指南。

  • 确保你的电脑上安装了Node.js
  • 确保你的电脑上安装了MongoDB,以及之前有使用MongoDB和MongoDB Atlas的知识。
  • 确保你安装了Postman以测试API端点。
  • 确保你的电脑上安装了Prisma。这里我们使用一个文本编辑器来编写这个模式。

确保你的文本编辑器中安装了Prisma,以帮助你编写类型安全的Prisma代码。例如,如果你使用Visual Studio Code,确保你安装了Prisma扩展。它为Prisma模式提供智能提示、格式化、自动补全、类型定义和提示功能。这可以确保你在创建Prisma模式时不会犯任何错误。

设置一个Node.js应用程序

创建一个项目文件夹,将其命名为prisma-server ,并使用Visual Studio代码打开它。我们将使用Node.js。在你所创建的目录内,使用npm init -y ,初始化Node.js。

然后使用npm install Prismanpm install @prisma/client --save-dev 安装Node.js Prisma包,以安装Prisma客户端。

npm init -y

npm install Prisma

npm install @prisma/client --save-dev

最后,运行npx prisma init ,在你的Node.js项目中初始化Prisma。

这将下载Node的Prisma引擎,然后自动创建一个带有schema.prisma 文件的Prisma文件夹。这就是你开始配置你的Prisma客户端、你想利用的数据库和你想表示的数据的地方。此外,在你的项目文件夹中还将创建一个.env 。这个文件用于存储敏感值,如你的数据库连接字符串。

设置MongoDB

正如我们所说,Prisma支持许多数据库。默认情况下,当你第一次初始化你的Prisma项目时,Prisma将PostgreSQL设置为数据库。让我们看看如何将MongoDB添加到Prisma中。

MongoDB Atlas是一个云托管平台,它将数据库作为一种服务运行。与其维护自己的服务器硬件来运行MongoDB,你可以使用MongoDB Atlas。它是一个完全管理的云数据库。

诸如基础设施、配置、数据库设置、数据库维护和版本升级等功能都是完全自动化的。Atlas对数据隐私和合规性有复杂的安全控制。

为了设置MongoDB Atlas,我们将使用一个免费层,帮助你开始测试MongoDB云生态系统。

一旦你建立了你的账户,创建一个免费层的共享集群。你的数据库将被设置为一个免费的MO Sandbox ,有一个共享集群,如下图所示。

free-mongodb-cluster

要将你的应用程序与设置的MongoDB Atlas连接起来,点击创建的集群上的连接按钮。这将提示你添加一个连接IP地址。为了本教程的目的,将其设置为允许从任何地方访问,然后点击添加IP地址进行设置。

要使用Atlas,你需要创建一个数据库用户。在提供的创建数据库用户表格中填写用户名密码,然后点击创建来设置数据库用户。

然后选择一个连接方法,选择Node.js驱动。这将为你提供一个连接字符串,让你的应用程序连接到Atlas。下面是一个带有所有必要参数的字符串连接样本。

mongodb+srv://<username>:<password>@cluster0.sium6.mongodb.net/myFirstDatabase?retryWrites=true&w=majority

在这种情况下。

  • <username> 是你的MongoDB Atlas集群的新添加的数据库用户的用户名
  • <password> 是你的MongoDB Atlas集群的新添加的数据库用户的密码
  • cluster0 是你的集群的默认名称
  • myFirstDatabase 是你的数据库名称。在这种情况下,你可以将其改为 。prisma-mongo

编辑你的连接字符串以反映你所使用的凭证。要使用该连接字符串,请前往你本地安装的MongoDB指南针,确保连接字符串格式正确,粘贴该字符串并点击连接

mongodb-compass-and-atlas-connection

这将连接到你的MongoDB远程Atlas集群,如下图所示。

mongodb-atlas-remote-connection

现在前往你的项目.env 文件,并添加MongoDB数据库连接字符串作为DATABASE_URL ,例如:DATABASE_URL="mongodb+srv://<username>:<password>@cluster0.sium6.mongodb.net/myFirstDatabase?retryWrites=true&w=majority"

使用Prisma进行数据建模

一旦你初始化你的Prisma项目,在schema.prismadatasourcegenerator ,创建两个主要代码块。

datasource 定义了连接的数据库。这需要两个主要参数, 和 。 设置你要使用的数据库,如 , , , 和 。provider url provider sqlite mysql mongodb postgresql sqlserver

url 读取数据库的连接字符串,这取决于托管你的首选数据库的服务器。我们已经在 文件中对此进行了设置。当制作产生实际数据库查询的数据数据库类型时, 决定应该创建哪些资产。.env generator

下面是使用MongoDB时应该如何设置datasourcegenerator

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

generator client {
  provider        = "prisma-client-js"
  previewFeatures = ["mongodb"]
}

现在让我们为我们的Prisma模式建模。

就在datasourcegenerator 块之后,我们可以在schema.prisma 文件内创建一个模型。要设置一个模型,你要使用关键字model ,后面跟着模型的名字,即。

model tasks { }

这个单一的模型将从MongoDB数据库中设置一个全新的JSON文档。现在让我们向这个模型添加一些字段。模型等同于关系数据库中的表。然而,在MongoDB中,模型要指向MongoDB集合。在这种情况下,模型的名称,即任务,将代表MongoDB集合。

model tasks {
  id    String @id @default(dbgenerated()) @map("_id") @db.ObjectId
  title String
  description String
  createdAt DateTime  @default(now())
}

在这里,我们为每个任务都有字段id,title,description, 和createdAt 。每个字段都有其数据库类型,如布尔型和字符串。

其他参数,如@default ,表示该特定字段将自动创建一个默认值。例如,dbgenerated() 表示每个任务将有一个自动生成的id值。createdAt ,当任务被创建时,该值将总是有当前的时间。

设置Prisma客户端

现在让我们创建一个Prisma客户端,并向我们创建的MongoDB数据库播种一些数据。首先,在你的项目文件夹中创建一个index.js 文件。

然后导入并创建一个Prisma客户端实例,开始使用Prisma。

const { PrismaClient } = require("@prisma/client");
const prisma = new PrismaClient();

继续创建async ,该函数将连接到我们先前创建的Prisma方案。然后使用create() ,添加你要播种的数据,如下图所示。

async function main() {
  await prisma.$connect();

  await prisma.tasks.create({
    data: {
      title: "Testing Node.js",
      description: "Create a Node.js tasks application",
    },
  });

  await prisma.tasks.create({
    data: {
      title: "Learning Java",
      description: "Creating some Java APIs",
    },
  });

  await prisma.tasks.create({
    data: {
      title: "Testing Out Flask APIs",
      description: "Set up some Flask APIs",
    },
  });

  const tasks = await prisma.tasks.findMany();

  console.dir(tasks, { depth: Infinity });
}

上面的代码块将为MongoDB数据库添加三个任务的种子。这也将把创建的任务记录到控制台。

最后,捕捉在播种这些数据时可能出现的任何错误。然后使用disconnect() ,一旦Prisma客户端执行了整个async main() 函数,就释放分配的资源。

main()
  .catch(console.error)
  .finally(() => prisma.$disconnect());

通过运行node index.js 来测试一下。

上面的任务列表将被记录到你的控制台。

console-tasks

前往你的MongoDB Atlasprisma-mongo 数据库,打开任务集合。我们创建的模式已经连接到MongoDB并添加了这些任务。

mongodb-tasks

在运行上述命令时,MongoDB可能会产生一个错误,如下图所示。

error

这主要发生在运行本地MongoDB部署时。为了解决这样的错误,建立一个MongoDB Atlas云数据库,并改变连接字符串以反映云托管的MongoDB Atlas。

创建一个MongoDB Prisma REST API

现在让我们创建一个服务器,利用MongoDB运行Prisma的优势。我们将建立一个基本的REST API,演示如何在一个典型项目中使用这个MongoDB-Prisma连接器。

首先,添加以下软件包,这将有助于使用Node.js部署一个HTTP服务器。

npm install cors dotenv express

当用Node.js构建服务器时,你可以选择Nodemon作为开发包,它将帮助你在做一些改变时自动重启服务器。

npm install nodemon --save-dev

要使用Nodemon,请编辑package.json 文件scripts 标签,如下图所示。

"scripts": {
  "dev": "nodemon index src/index.js"
}

在你的项目文件夹内,创建一个src 目录。然后在src ,创建一个controllers 目录,并添加一个新的TaskController.js 文件。

控制器有助于设置每个CRUD功能背后的逻辑。这是由实际的HTTP方法组成的,在Node.js REST API中使用的每个路由背后设置逻辑。

首先,导入PrismaClient ,创建一个Prisma客户端实例,开始使用Prisma。

const { PrismaClient } = require("@prisma/client");
const prisma = new PrismaClient();

然后添加REST API的CRUD控制器,如下所示。

AddTask

添加一个AddTask() ,执行一个POST方法的函数。在这种情况下,我们将使用Prisma方法prisma.tasks.create ,处理创建一个新任务背后的逻辑,如下所示。

async function AddTask(req, res) {
  try {
    const tasksdata = await prisma.tasks.create({
      data: {
        title: req.body.title,
        description: req.body.description,
      },
    });

    console.log(tasksdata);

    return res
      .status(201)
      .json({ msg: "Task Registration successfully Completed!" });
  } catch (error) {
    return res.status(400).json({ msg: "Unsuccessful Task Registration" });
  }
}

FetchAllTasks

创建一个FetchAllTasks() ,以获取所有在我们的mongodb数据库中创建和保存的任务。这里我们使用PrismafindMany() 函数。这个方法将找到并取回所有保存的任务。

async function FetchAllTasks(req, res) {
  try {
    const tasksdata = await prisma.tasks.findMany({
      select: {
        id: true,
        title: true,
        description: true,
        createdAt: true,
      },
    });

    return res.status(201).json(tasksdata);
  } catch (error) {
    return res.status(400).json({ msg: "Error Fetching Tasks" });
  }
}

FetchOneTask

如果你想获取一个单一的任务,你可以使用findUnique() 方法来实现。这将执行作为参数的任务id 。匹配所提供参数的任务将被获取。

async function FetchOneTask(req, res) {
  try {
    const tasksdata = await prisma.tasks.findUnique({
      where: {
        id: req.params.id,
      },
      select: {
        id: true,
        title: true,
        description: true,
        createdAt: true,
      },
    });

    return res.status(201).json(tasksdata);
  } catch (error) {
    return res.status(400).json({ msg: "Error Fetching Task" });
  }
}

UpdateOneTask

update Prisma方法帮助你访问一个已保存的任务并编辑该任务的任何细节。在这种情况下,我们只添加和更新titledescription 的值。

创建UpdateOneTask() 函数来执行这个逻辑。

async function UpdateOneTask(req, res) {
  try {
    await prisma.tasks.update({
      where: {
        id: req.params.id,
      },
      data: {
        title: req.body.title,
        description: req.body.description,
      },
    });

    return res.status(201).json({ msg: "Task successfully updated!!" });
  } catch (error) {
    return res.status(400).json({ error, msg: "Error updating task" });
  }
}

DeleteOneTask

要删除一个任务,使用delete() 方法。这将执行作为参数的任务id 。而与提供的参数相匹配的任务将被删除。

async function DeleteOneTask(req, res) {
  try {
    await prisma.tasks.delete({
      where: {
        id: req.params.id,
      },
    });

    return res.status(201).json({ msg: "Task successfully deleted!!" });
  } catch (error) {
    return res.status(400).json({ error, msg: "Error deleting task" });
  }
}

最后,导出上述所有函数,以便其他模块可以在应用程序中访问它们。

module.exports = {
  AddTask,
  FetchAllTasks,
  FetchOneTask,
  UpdateOneTask,
  DeleteOneTask,
};

添加路由

为了访问上述所有的CRUD控制器/函数,我们需要设置路由/端点,以帮助我们访问它们,并作为API端点运行它们。

要做到这一点,在src 目录内创建一个routes.js 文件,并根据每个CRUD功能添加以下路由。

const { Router } = require("express");
const TaskController = require("./controllers/TaskController");

const route = Router();

route.post("/tasks", TaskController.AddTask);
route.get("/tasks/:id", TaskController.FetchOneTask);
route.get("/tasks", TaskController.FetchAllTasks);
route.put("/tasks/:id", TaskController.UpdateOneTask);
route.delete("/tasks/:id", TaskController.DeleteOneTask);

module.exports = route;

设置服务器

为了运行上面的路由和控制器,我们将设置一个基本的服务器,它将在localhost上启动。这样,我们就可以在运行本地Node.js服务器的同时,使用Prisma来访问和设置tasks 到远程MongoDB。

src 目录内创建一个index.js 文件,并设置一个Express服务器,如下图所示。

const express = require("express");
const cors = require("cors");
const dotenv = require("dotenv");
const route = require("./routes");

const PORT = 3000;
const api = express();
dotenv.config();

api.use(express.json());
api.use(cors());
api.use(route);

api.listen(PORT, () => {
  console.log(`Tasks API server is running on Port: ${PORT}`);
});

测试REST API

应用程序已经准备好了,让我们来测试一下。首先运行prisma generate 。这将执行MongoDBprovider 并设置prisma-client

要运行服务器,使用命令npm run dev 。这将允许Nodemon启动和运行你的服务器,如下图所示。

task-api

让我们使用Postman来测试REST API是否工作。我们将从创建新任务开始。

前往Postman,从下拉菜单中选择POST方法,http://localhost:3000/tasks

create-task

这将创建一个新任务并保存到MongoDB数据库中。如果任务被成功保存,它将被记录到你的控制台,并在你的Postman上打印出一条成功信息。

{
  "msg": "Task Registration successfully Completed!"
}

尝试添加新的任务。如果你想获得所有添加的任务,请前往Postman,选择一个GET方法,http://localhost:3000/tasks

get-tasks

要获得单个任务,使用GET方法和URLhttp://localhost:3000/tasks/:id 。在这种情况下,用你想获取的任务ID替换:id

要更新任务的值,向http://localhost:3000/tasks/:id 发送一个PUT方法,其中:id 代表你要编辑的任务。下面是一个如何执行的例子。

update-a-task

当一个任务被成功更新时,新的值应该反映在你的数据库中。

最后,要删除一个任务,向http://localhost:3000/tasks/:id ,其中:id 代表你要删除的任务,如下图所示,发送一个删除方法。

delete-a-task

注意:在发送PUT或DELETE请求时,你可能会遇到一个错误响应。要解决这个问题,首先,停止你的服务器,运行prisma generate ,然后用npm run dev 重新运行你的服务器。

总结

SQL和NoSQL有不同的数据结构。本教程利用Prisma作为ORM,为MongoDB的JSON数据集创建方案。然后我们创建了一个服务器,利用Prisma与MongoDB一起运行的优势来展示MongoDB-Prisma连接器如何在一个典型项目中使用。

Prisma客户端会根据你想创建的数据库模型生成并提供函数或方法。我们使用这些函数来创建一个与数据库的有状态连接。然后,这将被用来创建、删除、更新或进行与数据库有关的操作。因此提供了非常简单和直观的步骤来设置这一切,而不需要手动编写一个数据库查询。