使用 Fastify 和 TypeScript 构建 Node.js API

阅读时长 16 分钟读完

在前端开发中,构建 API 是非常常见的任务。本文将介绍如何使用 Fastify 和 TypeScript 构建高效且类型安全的 Node.js API。所使用的技术栈如下:

  • Fastify:一个快速和低开销的 Web 框架;
  • TypeScript:一种静态类型检查的 JavaScript 的超集;
  • Jest:一个用于 JavaScript 测试的流行框架。

准备工作

在开始之前,你需要安装以下工具:

  • node.js 和 npm:在 https://nodejs.org/ 上下载安装包以安装;
  • TypeScript:在安装 npm 后,可以使用以下命令在全局安装 TypeScript:npm install -g typescript
  • Jest:可以使用以下命令在项目中进行安装:npm install jest @types/jest ts-jest -D

创建项目

我们将使用以下命令创建一个名为 fastify-typescript-api 的新项目:

接下来,我们将添加一些必要的依赖项:

这些依赖项包括:

  • fastifyfastify-corsfastify-helmet:Fastify 所需的必要插件;
  • fastify-plugin:一个 Fastify 插件,允许我们使用异步插件;
  • tslib:TypeScript 标准库的引用,支持在 JavaScript 运行时使用 TypeScript 的功能;
  • typescript:TypeScript 编译器;
  • @types/node:TypeScript 的 Node.js 类型定义。

配置 TypeScript

fastify-typescript-api 项目目录中创建一个新的 tsconfig.json 文件。在这个文件里,将代码源目录设置为 ./src,同时配置 TypeScript 编译器按照模块的引用方式("module": "CommonJS")将其编译到我们的输出目录 ./dist 中。tsconfig.json 应该如下:

-- -------------------- ---- -------
-
    ------------------ -
        --------- ------
        --------- -----------
        ------ ------- -------
        --------- ---------
        ---------- --------
        ------------ -----
        -------------- -----
        ------------------ -----
        -------------------- ----
    --
    ---------- -
        ----------
    --
    ---------- -
        ---------------
        --------------
    -
-

创建入口文件

将我们的 Fastify 实例创建在 ./src/server.ts 文件中。我们先从 fastify 包引入 Fastify,然后初始化一个实例:

创建插件

现在创建一个 Fastify 插件来设置我们的路由处理器。首先,为了使用异步函数,我们需要在 main 函数中使用 Fastify 插件 fastify-plugin。我们的路由处理器函数接受两个参数:请求对象(req)和回复对象(reply)。每个参数都有自己的类型,我们使用 TypeScropt 来保证类型安全。我们最终使用 Fastify 的 get 方法设置我们的路由处理器:

-- -------------------- ---- -------
------ - -- ------- ---- ----------
------ - -- ------ ---- -----------------
------ - -- ---- ---- ---------------
------ - -- -- ---- -----------------

----- -------- ------ -
    ----- ------ - --------- ------- ---- ---

    ------------------------
    ----------------------

    ------------------------ ---------- -------- ----- -- -
        ---------------------- ----- ----- ------ -- -
            -----------------------------------------
            ------ - -------- ------ ------ --
        ---
        -------
    ----

    ----- ------------------- -----------
    ------------------- ------- --------- -- -----------------
-

-------

在上面,我们使用了一些 Fastify 插件来促进我们的 REST API 的安全性和可用性。现在,我们可以运行我们的 API:tsc && node ./dist/server.js(在命令行中,使用 CTRL+C 退出服务器)。

现在,我们可以使用我们的 API 来通过 GET 请求显示 "Hello world"。这个 API 相当简单且有用,但对于一个真正的 API,我们需要做得更好。接下来,我们将使用一些更高级的快捷方式来进行设计。

重构

为了向更严格的代码分离和代码结构朝着正确的方向发展,我们需要再次重构我们的代码。首先我们创建一些必要的目录:

  • ./src/controllers:应用程序逻辑;
  • ./src/routes:Fastify 路线(路由);
  • ./src/interfaces:应用程序接口(TS 类型)。

./src/routes/index.ts 文件中,创建我们的路由:

-- -------------------- ---- -------
------ - -- ------- ---- ----------
------ - -- -- ---- -----------------
------ - ----------- - ---- ----------------

----- ------ - -------- ------------------------ ----- ---- ----- ---- -- -
    ---------------------------- - ------- -------- ---
    -------
--

------ ------- -----------

./src/routes/helloRouter.ts 文件中,创建我们的路由逻辑:

-- -------------------- ---- -------
------ - -- ------- ---- ----------
------ - -- -- ---- -----------------

----- ----------- - ---------- ------------------------ ----- ---- ----- ---- -- -
    ----------------- ----- ----- ------ -- --
        -------- ------ --------
    ----
    -------
--

------ - ----------- --

./src/interfaces/interfaces.ts 文件中,创建我们的接口(TypeScript 类型):

-- -------------------- ---- -------
--------- -------------- -
    -------- ----
    ------------ --------
    -----
    - -
        ------------- -------
    -
    - ------
-

------ - -------------- --

./src/controllers/helloController.ts 文件中,创建我们的逻辑:

最后在 ./src/app.ts 中,我们会初始化 Fastify,应用我们的路由,然后使用 fastify-ws 添加 WebSockets 支持:

-- -------------------- ---- -------
------ - -- ------- ---- ----------
------ - -- ------ ---- -----------------
------ - -- ---- ---- ---------------
------ - -------------- - ---- --------------------------
------ - -- -- ---- -----------------
------ ------ ---- -----------
------ - -- --------- ---- -------------

------ ----- --- -
    ------------------- --------- --------------- - -

    ----- ------- -
        ----- ------ - --------- ------- -------------------- ---

        ------------------------
        ----------------------
        ----------------------------

        ----- -------------------------- - ------- -------------------- ---

        ----- ------------------- -----------
        ------------------- ------- --------- -- -----------------
    -

    ------- --------------------------- ----------------------- -------- ------------------------------------ -
        ----------------------------
    -
-

最后,我们可以运行我们的 API:tsc && node ./dist/server.js,然后体验我们的最简单的 API 版本。

测试

最后,我们将使用 Jest 来编写测试及测试我们的 API。以下步骤建议你不要忽视,因为在编写测试及运行测试的版本处理和执行有一定差异性:

  • 将 TypeScript 与 Jest 集成;
  • 集成 TypeScript 代码覆盖率;
  • 编写测试用例。

将 TypeScript 与 Jest 集成

首先,我们将 TypeScript 与 Jest 集成。要做到这一点,我们需要安装一个 Jest 预处理器 ts-jest。同时在根目录下新建一个 jest.config.js 文件,内容如下:

安装:

集成 TypeScript 代码覆盖率

无论代码质量如何,在没有测试的情况下发布它不会是个好主意。获取良好的代码覆盖率,可以使测试人员的生活更加容易。要集成代码覆盖率,我们需要安装代码覆盖率库 @istanbuljs/nyc-config-typescript

在项目根目录创建一个 .nycrc 文件,内容如下:

-- -------------------- ---- -------
-
    ---------- ------------------------------------
    ------ -----
    ---------- -
        --------------
    --
    ----------- -
        -------
        ------
    --
    ----------------- ----
-

然后,添加以下脚本到 package.json

项目就可以生成浏览器中的代码测试覆盖率HTML报告。运行 npm run test 就可以看到HTML报告了。

编写测试用例

创建测试用例并分为以下几部分:

  • 测试控制器文件;
  • 测试测试用例文件。

./__tests__ 目录下创建 controllers 目录,并添加 helloController.spec.ts 文件:

-- -------------------- ---- -------
------ -------------------
------ - --------------- - ---- ----------------------------------------

--- ---------------- ----------------

------------ -- -
    --------------- - --- ------------------
---

--------------------------- -- -- -
    ---------- ------ ----- ------- ----- -- -- -
        ----- ------- - -- -- ----
        ----- --------- - -
            ----- ---------------------------
            ----- ---------------------------
            ----- ----------
        - -- ----

        ----- ----------------------------------- -----------

        ----------------------------------------------------------------
        -------------------------------------------------
        --------------------------------------------- -------- ------ ------ ---
    ---
---

然后创建另一个 __tests__ 的目录,并在其中添加 app.spec.ts 文件:

-- -------------------- ---- -------
------ - --- - ---- -------------
------ - -------------- - ---- -------------------------------
------ - -- ----- ---- --------
------ - -- --------- ---- -----

-----------------------

----- --------- -------------- - - ------- ----- --

--- ---- ----
--- ------- --------------------- - -----
--- --------- ------------------------ - -----

--------------- -- -- -
    --- - --- --------------
    ----- ------------

    -------- - ----------------------
        -------- ----------------------------
    ---

    ------ - --- ------------------ ----- ---- ---

    ----------------------- ---- -- -
        ---------------- --------- -- -
            ----- ------ - -------------------------------
            ------------------------ -------- ---------- ------------------ ----
        ---
    ---
---

----------- -- -
    ----------------
---

--------------- -- -- -
    ---------- --- ----- ----- -------- ----- -- -- -
        ----- - ------- ---- - - ----- ------------------------------------------------------

        -------------------------
        -------------------------------- --------
    ---

    ---------- --- ----- ----- -------------- ------ -- -
        ----- ------ - --- ---------------------------------------
        -------------------- --------- -- -
            -------------------------------------------------------------- ----- --------
            ---------------
            -------
        ---

        ----------------- -- -- -
            ---------------------------- -------- ------ ------ ----
        ---
    ---
---

结论

现在我们整合了 Fastify,TypeScript,Jest 和 Jest 的 TypeScript 模式,并生成了所有组成部分的基本框架。在容易参考和阅读的代码结构中,我们编写了一个简单的 API 并成功运行了它,然后增加了测试。开发者可以在具体的许可、管理和协议下复制任何部分或全部此代码,并对其进行使用,测试和修改。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/671b84619babaf620fac30db

纠错
反馈