返回

满怀期待的 Deno + mongodb 实战踩坑记

前端

自从 Deno 1.0 发布以来,有关 Deno 的文章很多,大多数都是在讨论怎么安装 Deno、Deno 有哪些特点、Deno 和 Node 有哪些异同、Deno 是不是 Node 的替代品等。咱们今天不讨论这些,毕竟 Talk is cheap. Show me the code。

本文将通过一个实战案例来介绍如何在 Deno 中使用 MongoDB。在实战过程中,作者遇到了几个坑,并给出了对应的解决方案。希望对其他有兴趣使用 Deno + MongoDB 的开发者有所帮助。

实战案例

我们将在 Deno 中创建一个简单的 Todo 应用。该应用将允许用户添加、列出、更新和删除 Todo 任务。

1. 创建 Deno 项目

首先,我们需要创建一个 Deno 项目。为此,请打开终端并运行以下命令:

deno init my_todo_app

这将在当前目录创建一个名为 my_todo_app 的新项目。

2. 安装依赖项

接下来,我们需要安装必要的依赖项。为此,请打开 my_todo_app 目录并运行以下命令:

deno install --unstable -A x/mongo

这将安装 MongoDB 驱动程序。

3. 创建数据库连接

现在,我们需要创建一个到 MongoDB 的连接。为此,请在 my_todo_app 目录中创建一个名为 db.ts 的文件,并添加以下代码:

import { MongoClient } from "x/mongo@v0.18.4";

const client = new MongoClient();
await client.connect("mongodb://localhost:27017");

export const db = client.database("my_todo_app");

4. 创建 Todo 模型

接下来,我们需要创建一个 Todo 模型。为此,请在 my_todo_app 目录中创建一个名为 todo.ts 的文件,并添加以下代码:

import { Schema, model } from "x/mongo@v0.18.4";

const todoSchema = new Schema({
  title: String,
  completed: Boolean,
});

export const Todo = model("Todo", todoSchema);

5. 创建 API 路由

现在,我们需要创建 API 路由。为此,请在 my_todo_app 目录中创建一个名为 api.ts 的文件,并添加以下代码:

import { serve } from "https://deno.land/std@0.126.0/http/server.ts";
import { Todo } from "./todo.ts";

const port = 8000;

serve(async (req) => {
  const { pathname } = new URL(req.url);

  switch (pathname) {
    case "/todos":
      return await handleTodos(req);
    default:
      return new Response("Not found", { status: 404 });
  }
}, { port });

async function handleTodos(req) {
  const { method } = req;

  switch (method) {
    case "GET":
      return await handleGetTodos();
    case "POST":
      return await handlePostTodo(req);
    default:
      return new Response("Method not allowed", { status: 405 });
  }
}

async function handleGetTodos() {
  const todos = await Todo.find();
  return new Response(JSON.stringify(todos), { status: 200 });
}

async function handlePostTodo(req) {
  const data = await req.json();
  const todo = new Todo(data);
  await todo.save();
  return new Response(JSON.stringify(todo), { status: 201 });
}

6. 运行应用

现在,我们可以运行应用了。为此,请打开终端并运行以下命令:

deno run --unstable --allow-net api.ts

这将在端口 8000 上启动应用。

7. 测试应用

现在,我们可以使用浏览器来测试应用了。在浏览器的地址栏中输入以下 URL:

http://localhost:8000/todos

这将显示所有 Todo 任务。

你也可以使用以下 URL 来添加新的 Todo 任务:

http://localhost:8000/todos

8. 踩坑记录

在使用 Deno + MongoDB 的过程中,作者遇到了几个坑。

  • 坑 1:无法使用 find() 方法

在使用 find() 方法时,作者遇到了一个错误:TypeError: Cannot read properties of undefined (reading 'filter')。这是因为 find() 方法需要一个查询参数,而作者没有提供查询参数。

为了解决这个问题,作者需要在 find() 方法中指定一个查询参数。例如,以下代码将查找所有已完成的 Todo 任务:

const todos = await Todo.find({ completed: true });
  • 坑 2:无法使用 save() 方法

在使用 save() 方法时,作者遇到了另一个错误:TypeError: Cannot read properties of undefined (reading 'insertOne')。这是因为 save() 方法需要一个文档对象,而作者没有提供文档对象。

为了解决这个问题,作者需要在 save() 方法中指定一个文档对象。例如,以下代码将保存一个新的 Todo 任务:

const todo = new Todo({ title: "Learn Deno", completed: false });
await todo.save();
  • 坑 3:无法使用 update() 方法

在使用 update() 方法时,作者遇到了另一个错误:TypeError: Cannot read properties of undefined (reading 'updateOne')。这是因为 update() 方法需要一个查询参数和一个更新操作,而作者没有提供查询参数和更新操作。

为了解决这个问题,作者需要在 update() 方法中指定一个查询参数和一个更新操作。例如,以下代码将把所有已完成的 Todo 任务标记为未完成:

await Todo.update({ completed: true }, { $set: { completed: false } });

结语

以上就是作者在使用 Deno + MongoDB 时遇到的几个坑。希望对其他有兴趣使用 Deno + MongoDB 的开发者有所帮助。