发布于 2026-01-06 7 阅读
0

使用 Fastify 构建 CRUD API

使用 Fastify 构建 CRUD API

大家好,本文我们将使用Fastify构建一个 NodeJS CRUD API。Fastify是一个用于构建快速 NodeJS 服务器的框架。借助这个强大的工具,您可以创建 NodeJS 服务器、创建路由(端点)、处理对每个端点的请求等等。

Fastify 是 Express(L express)的替代方案,如果您之前接触过 NodeJS,那么您应该听说过 Express。事实上,Fastify 的设计灵感正是来源于 Express,只是 Fastify 服务器的速度比 Express 服务器快得多。

我测试过,可以证明它的速度很快。我目前正在开发一个移动应用,在这个应用中,我使用 Fastify 作为我的 API。

因此,在本文中,我们将使用 Fastify 构建一个基本的 NodeJS 服务器。该服务器将包含创建数据、读取数据、更新数据和删除数据(CRUD)的接口。我们还将使用 JWT 进行一些身份验证(将在下一篇文章中介绍),以此向您展示 Fastify 插件生态系统及其强大之处。

前提条件:
在使用 Fastify 之前,您需要了解哪些内容?

  • JavaScript:你应该掌握相当数量的 JavaScript 知识,尤其是 ES5 和 ES6。Codecademy有很多很棒的课程可以指导你。
  • NodeJS:您还应该熟悉NodeJS。您可以在Codecademy上找到NodeJS课程。
  • Express:这完全是可选的,但如果你已经了解 Express,那么你学习 Fastify 粘贴的速度就会更快。

介绍就到此为止,让我们直接进入代码部分。

请在 GitHub 上查看完整代码

熟悉 Fastify

设置应用程序

就像我们用 Express 创建服务器并使用简单的端点来测试它是否运行一样,我将向您展示如何使用 Fastify 实现同样的功能。我们将初始化服务器,注册端口并监听该端口上的事件。

npm init -y让我们初始化一个 package.json 文件。你可以在终端中执行此操作,这将创建一个名为 package.json 的文件,其中包含一些关于你的应用程序的 JSON 信息。

现在我们来使用 NPM 安装 Fastify。您也可以使用 yarn。使用以下npm install Fastify命令安装 Fastify。我们还要安装的其他软件包有:

  • nodemon:用于在每次更改后自动重启服务器。我们将把此软件包作为开发依赖项安装。使用 NPM 是npm install -D nodemon……
  • 配置:用于存储密钥。当您想要发布到 GitHub 时非常有用。安装方法如下:npm install config

其他软件包将在需要时引入和安装。接下来,我们来设置 package.json 文件。

打开 package.json 文件,将 `<server_name>` 的值更改为main` server.js<server_name>`,因为我们将在其中创建服务器的文件名为 server.js。此外,删除 ` test<server_name>` 属性及其值。将以下代码粘贴到 ` script<server_name>` 属性中。

  "start": "node server.js",
  "server": "nodemon server.js"
Enter fullscreen mode Exit fullscreen mode

这意味着,当我们npm start在终端运行该命令时,它会运行即将创建的server.jsnpm run server文件。但是,当我们在终端运行该命令时,它会使用 nodemon 来运行server.js文件。

现在创建一个server.js文件,准备使用 Fastify 创建你的第一个 NodeJS 服务器。

创建我们的服务器

我们进入server.js文件并导入 Fastify。

const fastify = require('fastify')({ logger: true });
Enter fullscreen mode Exit fullscreen mode

logger: true;关键值是一个选项,用于启用 Fastify 在我们的终端上进行日志记录。这样,请求信息、服务器启动信息、响应信息和错误信息都将被记录到终端中。

接下来,我们需要将端口号分配给一个PORT变量,我这里用的是 5000。之所以要创建一个变量,是为了方便部署到生产环境。所以你应该会看到类似这样的代码const PORT = process.env.PORT || 5000。这样一来,我们要么使用的是托管公司(例如 Heroku 或 Digital Ocean)提供的端口,要么使用的是我们自定义的 5000 端口。

现在让我们创建一个简单的路由,用于向/.

fastify.get('/', (req, reply) => {
  reply.send('Hello World!');
});
Enter fullscreen mode Exit fullscreen mode

是不是很眼熟?看起来和 Express 很像吧?没错,所以对于已经熟悉 Express 的人来说,使用 Fastify 会非常容易,因为它们的语法很相似。

req`and`reply分别代表请求和回复(响应)。它们显然是参数,所以你可以随意命名。但我们建议使用这种简洁易读的形式。

好了,现在让我们通过监听事件来启动服务器。我们之前会fastify.listen(port)监听服务器收到的请求。但是这个函数会返回一个 Promise 对象,所以我们需要创建一个使用 async 和 await 来处理这个 Promise 的函数。

const startServer = async () => {
  try {
    await fastify.listen(PORT);
  } catch (err) {
    fastify.log.error(err);
    process.exit(1);
  }
};
Enter fullscreen mode Exit fullscreen mode

你需要确保记录错误日志,并在发生错误时退出服务器。现在我们可以直接在终端上调用startServer()并运行npm run server命令来启动服务器。

Fastify API

你应该能在终端的日志信息中看到你的 URL 地址,就像上图所示,或者直接使用 `.` 命令http://localhost:5000。使用你选择的任何 API 测试工具进行测试,你应该会收到“Hello world”作为响应。

创建更多路线

你肯定不希望所有的路由都放在server.js文件里,所以我们会创建一个名为routes 的文件夹。我们将用它来管理和组织 API 的所有不同路由。

这个 API 将用于博客,所以我们的数据主要关于博文以及发布这些博文的管理员。因此,在routes文件夹中,创建 posts.js 和admins.js文件。

为了让这些文件作为服务器端点正常工作,我们需要将它们注册为插件。别担心,这比你想象的要简单。只需将以下代码添加到server.js 文件中的相应函数之前即可startServer

fastify.register(require('./routes/posts')); // we will be working with posts.js only for now
Enter fullscreen mode Exit fullscreen mode

这样就能注册 POST 路由。你可以先导入并将其赋值给一个变量,然后将该变量作为参数传递给register函数,选择权在你。

如果保存,将会产生错误,这是因为我们还没有在posts.js中创建任何路由。

posts.js 文件中,创建一个名为 `fastify` 的函数postRoutes,并传递三个参数:`fastify``options`和 ` done` 。这个函数会创建一个 fastify 服务器实例,这意味着通过第一个参数,我们可以实现之前在server.js文件中使用 `options` 变量所能做的一切fastify

现在你可以将server.js中的 get 请求剪切posts.jspostRoutes中的函数中。

你的postRoutes文件应该看起来像这样:

const postRoutes = (fastify, options, done) => {
  fastify.get('/', (req, reply) => {
    reply.send('Hello world');
  });
};
Enter fullscreen mode Exit fullscreen mode

options (有时写作opts )参数用于路由选项,我们不会使用它。

`done`参数是一个函数,我们会在函数结束时调用它postRoutes,以表明程序已完成。这就像在 Express 中创建一个中间件,然后调用 `next` 继续执行一样。

所以你应该把它done()放在函数的最后一行postRoutes

现在,让我们导出该函数并保存文件。在posts.js文件的最后一行使用以下命令进行导出:module.exports = postRoutes.

保存文件并测试路线。

路线规划

我们可以创建更多类似上面那样的路由,然后就此收工,但这会让我们无法充分利用 Fastify 的一些强大功能。借助 Fastify,我们可以通过分离关注点来更好地组织 API。

借助 Fastify,我们可以为路由接收到的请求和路由发送的响应创建模式。对于请求,我们可以告诉 Fastify 请求体、请求头、请求参数等应该包含哪些内容。

我们还可以告诉 Fastify 我们打算发送什么作为响应,例如在 200 响应、400 响应或 500 响应等情况下将发送的数据。

例如,让我们为上面的 GET 请求创建一个模式。在我们的 GET 请求中,我们发送了“Hello world”(一个字符串)作为响应,现在我们将发送一个帖子数组,如下所示。

fastify.get('/', (req, reply) => {
  reply.send([
    { id: 1, title: 'Post One', body: 'This is post one' },
    { id: 2, title: 'Post Two', body: 'This is post two' },
    { id: 3, title: 'Post Three', body: 'This is post three' },
  ]);
});
Enter fullscreen mode Exit fullscreen mode

我们来创建它的模式。在 Fastify 中,模式是一个对象,这个对象将作为属性的值传递schema

const opts = {
  schema: {},
};

const postRoutes = (fastify, options, done) => {
  fastify.get('/', opts);

  done();
};
Enter fullscreen mode Exit fullscreen mode

我们将以这种方式定义我们的路由,get 方法(可以是 post 或任何方法)将接受两个参数,第一个参数是路由,最后一个参数是选项对象。

我们将在此 API 中使用的选项对象的三个属性是:

  • schema:定义了我们的数据应该如何设置,哪些数据应该输入,哪些数据应该输出,包括它们的类型(字符串、布尔值、数字等)。

  • preHandler:一个定义在以下函数处理请求之前应该执行的操作的函数handler

  • handler:处理请求的函数。

你现在可能还不清楚,但我们举个例子你就会明白了。这个preHandler将用于身份验证,这意味着它只会用于受保护的路由。

解释就到此为止,如果想了解更多,请查看文档。接下来我们直接看代码。

我们的 GET 请求即将变得更好。

const opts = {
  schema: {
    response: {
      200: {
        type: 'array',
        items: {
          type: 'object',
          properties: {
            id: { type: 'number' },
            title: { type: 'string' },
            body: { type: 'string' },
          },
        },
      },
    },
  },
  handler: (req, reply) => {
    reply.send([
      { id: 1, title: 'Post One', body: 'This is post one' },
      { id: 2, title: 'Post Two', body: 'This is post two' },
      { id: 3, title: 'Post Three', body: 'This is post three' },
    ]);
  },
};
Enter fullscreen mode Exit fullscreen mode

虽然现在情况有所改善,但我估计也更令人困惑了。好吧,很简单,我们来分析一下模式对象。

模式

在模式对象中,我们告诉 Fastify,当响应状态码为 200 时,我们将发送一个数组。该数组中的每个元素都是一个对象,这些对象的属性分别为 `a` id、 `b`title和`c`,body它们的类型分别为 `a` numberstring`b` 和`c` string

很简单,对吧?你应该记下所用属性的名称,例如 `a` response200`b` 和type`c`。`a` 和 ` itemsc`properties可以是任何名称,但我建议使用这些名称。

如果你尝试id从模式对象中移除该属性及其值,你会发现该id属性不再作为响应的一部分发送。而如果你尝试将该id属性的类型从 `type`更改number为 `type` string,你会在响应中看到它以字符串的形式出现。很酷吧!

处理程序

处理函数非常清晰,我们只是简单地复制了我们在 GET 请求中的代码。

opts对象是特定于某个路由的。除非你想用同一个响应处理不同路由上不同请求。如果不是这种情况,那么你应该确保该对象的名称是唯一的。

例如,在我们的 GET 请求中,由于我们获取的是帖子,我们可以将名称更改为getPostsOpts

我们的posts.js 文件现在应该看起来像这样

const getPostsOpts = {
  schema: {
    response: {
      200: {
        type: 'array',
        items: {
          type: 'object',
          properties: {
            id: { type: 'number' },
            title: { type: 'string' },
            body: { type: 'string' },
          },
        },
      },
    },
  },
  handler: (req, reply) => {
    reply.send([
      { id: 1, title: 'Post One', body: 'This is post one' },
      { id: 2, title: 'Post Two', body: 'This is post two' },
      { id: 3, title: 'Post Three', body: 'This is post three' },
    ]);
  },
};

const postRoutes = (fastify, options, done) => {
  fastify.get('/', getPostsOpts);

  done();
};
Enter fullscreen mode Exit fullscreen mode

现在想象一下,你有 10 条路由,每条路由都有不同的模式和处理程序,可能还有一些预处理程序。你可以想象,代码会变得非常复杂,难以阅读。这时,控制器就派上用场了。

Controllers 并非像听起来那样是一种插件或包。它只是一个文件夹,我们用它来将路由与模式和处理程序分开。

在controllers文件夹内,我将创建两个名为 schemas 和 handlers 的文件夹。这样可以使目录结构更清晰,更易于阅读。

在我们的schemas文件夹中,我们将创建一个名为 posts.js 的文件该文件将包含我们所有帖子路由的 schema(获取所有帖子、创建帖子、删除帖子等)。

schemas/posts.js 文件中,创建一个名为 `<object>` 的对象getPostsSchema,并将 `<property>` 属性的值schema(来自routes/posts.js 文件)剪切下来,粘贴到该对象中。你的代码应该如下所示:

const getPostsSchema = {
  response: {
    200: {
      type: 'array',
      items: {
        type: 'object',
        properties: {
          id: { type: 'number' },
          title: { type: 'string' },
          body: { type: 'string' },
        },
      },
    },
  },
};
Enter fullscreen mode Exit fullscreen mode

现在我们把它导出;

const getPostsSchema = {
  // our schemas
};

module.exports = { getPostsSchema };
Enter fullscreen mode Exit fullscreen mode

我们将在routes/posts.js文件中导入它,以便我们可以将其用作属性的值schema

const { getPostsSchema } = require('../controllers/schemas/posts.js');

const getPostsOpts = {
  schema: getPostsSchema,
  handler: (req, reply) => {
    reply.send([
      { id: 1, title: 'Post One', body: 'This is post one' },
      { id: 2, title: 'Post Two', body: 'This is post two' },
      { id: 3, title: 'Post Three', body: 'This is post three' },
    ]);
  },
};
Enter fullscreen mode Exit fullscreen mode

在我们的handlers文件夹中,我们创建一个名为posts.js 的文件。该文件将包含我们所有 post 路由的处理函数(获取所有帖子、创建帖子、删除帖子等)。

handlers/posts.js 文件中,创建一个名为 `get_posts_name` 的函数getPostsHandler,并将 `$_posts_name`reqreply`$_posts_name` 作为参数。从routes/posts.js文件中复制函数体并粘贴到这里,然后导出该函数。它应该看起来像这样:

const getPostsHandler = (req, reply) => {
  reply.send([
    { id: 1, title: 'Post One', body: 'This is post one' },
    { id: 2, title: 'Post Two', body: 'This is post two' },
    { id: 3, title: 'Post Three', body: 'This is post three' },
  ]);
};

module.exports = { getPostsHandler };
Enter fullscreen mode Exit fullscreen mode

将其导入getPostsHandlerroutes/posts.js文件中,并将其设置为处理程序方法的值。您的routes/posts.js 文件应如下所示:

const { getPostsSchema } = require('../controllers/schemas/posts.js');
const { getPostsHandler } = require('../controllers/handlers/posts.js');

const getPostsOpts = {
  schema: getPostsSchema,
  handler: getPostsHandler,
};

const postRoutes = (fastify, opts, done) => {
  fastify.get('/', getPostsOpts);

  done();
};
Enter fullscreen mode Exit fullscreen mode

这样看起来更简洁了吧?现在保存文件并测试一下,应该和以前一样可以正常工作了。

我很想在这里谈谈如何组织身份验证,但这会让这篇文章太长,所以我将另写一篇文章来讨论身份验证。

好了,Elijah,我们能直接构建CRUD API了吗?当然可以!

使用 Fastify 构建您的第一个 CRUD API

我们将创建一个博客 API,用于创建文章、读取所有文章、阅读文章、删除文章和更新文章。我们还将能够创建管理员、登录管理员以及创建受保护的路由。但这些内容将在另一篇文章中介绍。

查看所有帖子

由于我们已经有了可用的 GET 请求,我将对路由和帖子数组进行一些更改。

routes/posts.js中。

fastify.get('/api/posts', getPostsOpts);
Enter fullscreen mode Exit fullscreen mode

这样应该能让路由看起来更像一个 API 端点。

让我们在根目录下创建一个名为cloud 的文件夹,并在其中创建一个名为posts.js 的文件。这个文件将作为我们的数据库,因为我们会将所有文章存储在其中。将以下代码粘贴到该文件中:

const posts = [
  { id: 1, title: 'Post One', body: 'This is post one' },
  { id: 2, title: 'Post Two', body: 'This is post two' },
  { id: 3, title: 'Post Three', body: 'This is post three' }, // you can add as many as you want
];

module.exports = posts;
Enter fullscreen mode Exit fullscreen mode

handlers/posts.js 文件中,导入 posts 并将其替换为函数中的数组send,即

handlers/posts.js中。

const posts = require('../../cloud/posts.js');

const getPostsHandler = (req, reply) => {
  reply.send(posts);
};

module.exports = { getPostsHandler };
Enter fullscreen mode Exit fullscreen mode

保存文件并运行程序,请注意路线已更改。要获取所有帖子,请使用http://localhost:your_port/api/posts

注意:有四个名为posts.js 的文件。

  • cloud/posts.js:存储帖子数组的地方(我们的数据库)。
  • routes/posts.js:我们在这里处理博客文章的所有路由。
  • handlers/posts.js:我们在这里处理对 post 路由的响应。
  • schemas/posts.js:我们在此处指定 post 路由的模式。

我会将他们每个人与各自的文件夹对应起来,方便您区分。

获取帖子

接下来我们要做的就是获取一篇帖子,我们会使用帖子的 ID。所以我们会id从请求中获取一个 ID 参数,然后筛选数组posts来找到这篇帖子。

在routes/posts.js中创建路由

routes/posts.js 文件中,紧接第一个路由下方,粘贴以下代码。

fastify.get('/api/posts/:id', getPostOpts); // the :id route is a placeholder for an id (indicates a parameter)
Enter fullscreen mode Exit fullscreen mode

让我们创建getPostOpts对象

const getPostOpts = {
  schema: getPostSchema, // will be created in schemas/posts.js
  handler: getPostHandler, // will be created in handlers/posts.js
};
Enter fullscreen mode Exit fullscreen mode

在schemas/posts.js中创建模式

创建一个名为 `<object>` 的对象getPostSchema,并将以下内容粘贴到其中。

const getPostSchema = {
  params: {
    id: { type: 'number' },
  },
  response: {
    200: {
      type: 'object',
      properties: {
        id: { type: 'number' },
        title: { type: 'string' },
        body: { type: 'string' },
      },
    },
  },
};
Enter fullscreen mode Exit fullscreen mode

`params` 属性指示路由参数中应收集哪些数据。我用它来将 id 格式化为数字。默认值为字符串。由于我们文章数组中的 id 都是数字,所以我希望它们的数据类型相同。

由于我们只获取一个帖子,这意味着我们的响应将是一个包含 id、title 和 body 三个属性的对象。导出时getPostSchema,只需将其添加到要导出的对象中即可。module.exports = { getPostsSchema, getPostSchema };

现在仔细查看一下你的routes/posts.js 文件,你会发现你重复编写了代码。所以重构一下,确保没有重复,我就是这么做的。

const typeString = { type: 'string' }; // since i will be using this type a lot

const post = {
  type: 'object',
  properties: {
    id: { type: 'number' },
    title: typeString,
    body: typeString,
  },
};

const getPostsSchema = {
  response: {
    200: {
      type: 'array',
      items: post,
    },
  },
};

const getPostSchema = {
  params: {
    id: { type: 'number' },
  },
  response: {
    200: post,
  },
};

module.exports = { getPostsSchema, getPostSchema };
Enter fullscreen mode Exit fullscreen mode

在handlers/posts.js中创建处理程序

handlers/posts.js 文件中,创建一个名为 `posts` 的对象getPostHandler,并将以下内容粘贴到其中。

const getPostHandler = (req, reply) => {
  const { id } = req.params;

  const post = posts.filter((post) => {
    return post.id === id;
  })[0];

  if (!post) {
    return reply.status(404).send({
      errorMsg: 'Post not found',
    });
  }

  return reply.send(post);
};
Enter fullscreen mode Exit fullscreen mode

函数体的第一行代码用于从请求路由中获取 id。因此,像这样的路由http://localhost:5000/api/posts/4将返回 id 为 4。

reply.status函数告诉 Fastify 响应应该是什么状态码。如果找不到 POST 请求,则会发送自定义错误消息;使用 Fastify,我们还可以……

return reply.status(404).send(new Error('Post not found'));
Enter fullscreen mode Exit fullscreen mode

因此,当找不到帖子时,Fastify 会发送以下 JSON 作为响应。

{
  "statusCode": 404,
  "error": "Not Found",
  "message": "Post not found"
}
Enter fullscreen mode Exit fullscreen mode

现在导出getPostHandler并保存所有文件。运行程序并测试你的新路线。

创建新帖子

在routes/posts.js中创建路由

首先,让我们在函数中创建路由postRoutes。在上一个创建的路由之后,粘贴以下代码。

fastify.post('/api/posts/new', addPostOpts);
Enter fullscreen mode Exit fullscreen mode

/api/posts/new这是我们向帖子数组添加新帖子的端点。接下来,我们需要addPostOpts在路由函数之外创建对象,并传递模式和处理程序的值。

const addPostOpts = {
  schema: addPostSchema, // will be created in schemas/posts.js
  handler: addPostHandler, // will be created in handlers/posts.js
};
Enter fullscreen mode Exit fullscreen mode

在我的下一篇文章中,我将把这条路由设为私有路由,这意味着我们将preHandler在下一篇文章中向上面的对象添加一个。

在schemas/posts.js中创建模式

我们将告诉 Fastify 请求正文中应该包含哪些数据,以及我们将作为响应发送哪些数据。

创建一个名为`<object>`的对象addPostSchema,并将以下代码赋值给它;

const addPostSchema = {
  body: {
    type: 'object',
    required: ['title', 'body']
    properties: {
      title: typeString, // recall we created typeString earlier
      body: typeString,
    },
  },
  response: {
    200: typeString, // sending a simple message as string
  },
};
Enter fullscreen mode Exit fullscreen mode

我们使用 ` bodyrequest_body` 作为属性,告诉 Fastify 应该从 POST 路由的请求体中获取什么内容。就像我们params上面所做的那样。我们也可以对 `request_body` 做同样的操作headers(我将在身份验证期间向您展示这一点)。

通过该required属性,我们告诉 Fastify,如果两者都不是请求正文的一部分title,则返回错误。body

如果缺少必填字段,Fastify 将返回400 Bad Request错误作为响应。

添加到从此文件( schemas/posts.jsaddPostSchema )导出的对象中

在handlers/posts.js中创建处理程序

我们将为收到的数据创建一个 ID,并将其添加到我们的帖子数组中。很简单,对吧!

const addPostHandler = (req, reply) => {
  const { title, body } = req.body; // no body parser required for this to work

  const id = posts.length + 1; // posts is imported from cloud/posts.js
  posts.push({ id, title, body });

  reply.send('Post added');
};
Enter fullscreen mode Exit fullscreen mode

添加到从该文件( handlers/posts.jsaddPostHandler )导出的对象中

在保存文件并运行程序之前,请确保将 ` addPostSchemaand`添加addPostHandler到导入到routes/posts.js 的对象中。

要验证您的帖子是否已创建,您可以运行http://localhost:your_port/api/posts(我们的第一个端点),您会在数组底部看到它。

更新帖子

在routes/posts.js中创建路由

我们将使用这种put方法来处理这条路由。请将以下代码添加到您的postRoutes函数中。

fastify.put('/api/posts/edit/:id', updatePostOpts);
Enter fullscreen mode Exit fullscreen mode

接下来,我们需要在函数updatePostOpts外部创建对象postRoutes。和之前一样,我们会为 ` schemaand`handler属性传递一个值,即 `ie`。

const updatePostOpts = {
  schema: updatePostSchema, // will be created in schemas/posts.js
  handler: updatePostHandler, // will be created in handlers/posts.js
};
Enter fullscreen mode Exit fullscreen mode

在切换到其他文件之前,请快速updatePostSchema将以下内容添加updatePostHandler到此文件(routes/posts.js)中的导入对象。

在schemas/posts.js中创建模式

创建一个名为 `<object>` 的对象updatePostSchema,并使用以下代码来操作它。

const updatePostSchema = {
  body: {
    type: 'object',
    required: ['title', 'body'],
    properties: {
      title: typeString,
      body: typeString,
    },
  },
  params: {
    id: { type: 'number' }, // converts the id param to number
  },
  response: {
    200: typeString, // a simple message will be sent
  },
};
Enter fullscreen mode Exit fullscreen mode

别忘了在updatePostSchema要导出的对象中添加该属性。

在handlers/posts.js中创建处理程序

const updatePostHandler = (req, reply) => {
  const { title, body } = req.body;
  const { id } = req.params;

  const post = posts.filter((post) => {
    return post.id === id;
  })[0];

  if (!post) {
    return reply.status(404).send(new Error("Post doesn't exist"));
  }

  post.title = title;
  post.body = body;

  return reply.send('Post updated');
};
Enter fullscreen mode Exit fullscreen mode

别忘了在updatePostHandler要导出的对象中添加该属性。

现在您可以保存文件并测试新路线了。

删除帖子

在routes/posts.js中创建路由

我们将沿用之前路线的相同流程,只会改变路线和方法。

fastify.delete('/api/posts/:id', deletePostOpts);
Enter fullscreen mode Exit fullscreen mode

deletePostOpts对象将是

const deletePostOpts = {
  schema: deletePostSchema,
  handler: deletePostHandler,
};
Enter fullscreen mode Exit fullscreen mode

在schemas/posts.js中创建模式

需要注意的是,创建模式是完全可选的,对于这样的路由,您可能不需要创建模式。

const deletePostSchema = {
  params: {
    id: { type: 'number' }, // converts the id param to number
  },
  response: {
    200: typeString,
  },
};
Enter fullscreen mode Exit fullscreen mode

在handlers/posts.js中创建处理程序

const deletePostHandler = (req, reply) => {
  const { id } = req.params;

  const postIndex = posts.findIndex((post) => {
    return post.id === id;
  });

  if (postIndex === -1) {
    return reply.status(404).send(new Error("Post doesn't exist"));
  }

  posts.splice(postIndex, 1);

  return reply.send('Post deleted');
};
Enter fullscreen mode Exit fullscreen mode

导出你的处理程序和模式,并相应地在routes/posts.js中导入它们。保存文件并测试你的新路由。

结语

这是我对本文的最后总结,并非针对 Fastify 的总结。我们尚未添加涉及身份验证的管理员路由。我们将在下一步添加此功能,因此请务必关注其发布通知。

综上所述,我要祝贺你使用 Fastify 构建了你的第一个 CRUD API。在这个项目中,我们创建了创建数据、读取数据、更新数据和删除数据的路由。我们也简单介绍了一下 Fastify。干得漂亮!

如果您觉得这篇文章有用,请点赞并分享。您也可以请我喝杯咖啡以示支持。感谢阅读,祝您编程愉快!

文章来源:https://dev.to/elijahtrillionz/build-a-crud-api-with-fastify-688