TypeScript 下使用 Node.js 开发 RESTful API 的实际案例

随着前端技术的不断发展,Node.js 作为后端开发的一个重要选择,在开发 RESTful API 的过程中,也成为了不可或缺的角色。而 TypeScript 这个静态类型语言,可以极大地提高开发效率和代码可维护性。本文将介绍一个实际案例,带大家一步步学习在 TypeScript 下使用 Node.js 开发 RESTful API。

实际案例背景

我们假设有一个简单的需求,需要开发一个博客系统后端,实现以下功能:

  • 用户注册、登录、注销;
  • 博客的增删改查;
  • 文件的上传和下载。

开发环境搭建

首先,我们需要搭建开发环境,安装以下工具:

  • Node.js:可以到官网下载和安装;
  • TypeScript:可以通过 npm 安装;
  • MongoDB:可以到官网下载和安装;
  • Postman:测试 RESTful API 的工具,可以到官网下载。

接下来,我们创建一个空的 Node.js 项目。使用以下命令初始化项目:

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

然后,我们安装以下依赖:

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

上面的依赖中,expressbody-parser 是用于创建和解析 HTTP 请求的,mongoose 是用于操作 MongoDB 的,multer 是用于处理文件上传的,jsonwebtokenbcryptjs 是处理用户认证和密码加密的,cors 是处理跨域访问的。typescript 是 TypeScript 的运行环境,@types/* 是用于添加 TypeScript 安装的第三方库类型定义文件(声明文件)。

代码实现

接下来,我们来实现上述功能。为了提高可维护性和可读性,我们将代码分成多个文件来实现。

配置

首先,我们新建一个 config.ts 文件,用于配置应用的一些变量和选项:

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

上述配置中,PORT 是应用监听的端口,SECRET_KEY 是 JWT 生成 token 和验证 token 的密钥,MONGODB_URI 是 MongoDB 的连接地址,UPLOADS_DIR 是上传文件保存的目录,CORS_ORIGIN 是 CORS 的跨域访问源。

数据模型

接下来,我们定义数据模型,使用 Mongoose 来操作 MongoDB。新建 model.ts 文件:

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

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

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

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

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

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

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

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

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

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

上述代码中,我们定义了三个数据模型:UserBlogFile。每个模型都有一个对应的 Schema,用于约束数据的字段和类型。我们使用 mongoose 的 model() 方法来创建 Mongoose 模型,并导出给其他文件使用。

路由

接下来,我们定义路由,使用 Express 框架来实现。新建 routes.ts 文件:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

上述代码中,我们定义了如下路由:

  • /api/register:实现用户注册,如果邮箱已被注册,则返回 409,否则创建新用户并返回 201
  • /api/login:实现用户登录,如果邮箱或密码错误,则返回 401,否则生成 JWT token 并返回;
  • /api/logout:TODO 实现用户注销;
  • /api/blogs:实现获取所有博客、创建新博客等功能;
  • /api/blogs/:id:实现获取单个博客、更新博客和删除博客等功能;
  • /api/files:实现文件上传,使用 multer 中间件处理,上传的文件保存在本地磁盘,并保存文件信息到数据库中;
  • /api/files/:filename:实现文件下载,根据文件名从数据库中查找文件信息,将文件下载到客户端。

其中,authMiddleware 是一个自定义的中间件,用于验证 JWT token 是否有效。如果 token 验证失败,则返回 401

中间件

接下来,我们定义一些中间件函数,用于处理请求和错误。新建 middleware.ts 文件:

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

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

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

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

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

上述代码中,我们定义了如下中间件:

  • errorHandlerMiddleware:处理服务器内部错误,如果出错,则返回 500
  • notFoundMiddleware:处理资源不存在错误,如果路由不匹配,则返回 404
  • authMiddleware:处理 JWT 认证,验证请求头中的 token 是否有效,如果认证失败,则返回 401

文件上传

接下来,我们实现文件上传逻辑,创建 utils/multer.ts 文件:

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

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

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

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

上述代码中,我们使用 multer 模块创建了一个 storage 对象,用于保存上传的文件。同时,我们定义了一个 fileFilter 回调函数,用于过滤非图片文件。

启动应用

最后,我们在 index.ts 文件中启动应用:

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

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

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

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

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

上述代码中,我们使用 mongoose 连接 MongoDB 数据库,并使用 express 启动应用。在启动应用前,使用 use() 方法添加中间件、路由等。

总结

本文介绍了如何使用 TypeScript 和 Node.js 开发 RESTful API,实现了用户注册、登录、注销、博客的增删改查,文件上传和下载等功能。通过本文的实际案例,相信大家已经掌握了 TypeScript 下使用 Node.js 开发 RESTful API 的基本流程和思路。

来源:JavaScript中文网 ,转载请联系管理员! 本文地址:https://www.javascriptcn.com/post/64f047e6f6b2d6eab3a41da5


猜你喜欢

  • GraphQL:用 Connection 优化节点查询

    前言 GraphQL 是一种由 Facebook 开发的数据查询和操作语言,它提供了一种更高效、更灵活的方式来获取和操作数据。GraphQL 的一个重要特性就是可以精确地指定需要查询的数据,避免了传统...

    2 个月前
  • Server-sent Events 的浏览器支持情况及解决方法

    什么是 Server-sent Events? Server-sent Events(简称 SSE)是一种基于 HTTP 的服务器推送技术,它可以让服务器向客户端发送事件流,客户端通过监听这个事件流来...

    2 个月前
  • ECMAScript 2020(ES11)中的新特性:BigInt 转换

    在 ECMAScript 2020(ES11)中,新增了一种数据类型:BigInt。它是一种可以表示任意大整数的数据类型,可以用来解决 JavaScript 中整数运算的精度问题。

    2 个月前
  • CSS Reset 在 IE6、IE7 等老浏览器中的应用

    什么是 CSS Reset CSS Reset 是一种通过重置浏览器默认样式的方式,消除不同浏览器之间的差异,从而实现更加一致的样式效果的技术手段。在前端开发中,使用 CSS Reset 可以让我们更...

    2 个月前
  • ES6 中的类继承和原型链之间的关系解析

    在 ES6 中,引入了 class 关键字,使得 JavaScript 也具备了面向对象编程的能力。在类继承和原型链之间,有着密切的关系。本文将详细解析 ES6 中的类继承和原型链之间的关系,并提供一...

    2 个月前
  • 如何使用 Redux 处理 React 应用中的表单数据

    前言 在开发 React 应用时,表单数据的处理是非常常见的需求。然而,由于 React 的单向数据流和组件化特性,传统的表单处理方式可能会变得非常繁琐。而 Redux 作为一种状态管理工具,可以帮助...

    2 个月前
  • Redis 处理高并发的策略

    前言 随着互联网的发展,高并发已经成为了一个不可避免的问题。而 Redis 作为一款高性能的 NoSQL 数据库,也成为了处理高并发的重要工具之一。本文将会介绍 Redis 处理高并发的策略,并且会提...

    2 个月前
  • 响应式设计中的图片适配问题解决方案

    在响应式设计中,图片适配是一个比较棘手的问题。如果不加以处理,可能会导致图片在不同设备上显示不佳,影响用户体验。本文将介绍响应式设计中的图片适配问题,并提供解决方案。

    2 个月前
  • 解析 TypeScript 中 encapsulation(封装)的实现方式

    解析 TypeScript 中 encapsulation(封装)的实现方式 在 TypeScript 中,封装(encapsulation)是一种重要的面向对象编程的特性。

    2 个月前
  • PM2 崩溃处理:如何避免由于 PM2 进程奔溃导致应用崩溃?

    在前端开发中,我们经常使用 PM2 进行进程管理和部署。但是,当 PM2 进程崩溃时,应用也会跟着崩溃。如何避免这种情况的发生?本文将介绍 PM2 崩溃处理的方法和技巧,帮助您更好地管理和部署应用。

    2 个月前
  • 在 Node.js 中运行 HTTPS 服务器的方法

    Node.js 是一个非常流行的 JavaScript 运行时环境,它可以让我们通过 JavaScript 编写服务器端应用程序。在开发 Web 应用程序时,安全性是非常重要的。

    2 个月前
  • 详解 ECMAScript 2018 中的三个新操作符及其用法

    ECMAScript 2018 (简称 ES2018) 是 JavaScript 语言的最新标准,其中包含了许多新特性和语法糖。本文将详细介绍其中的三个新操作符及其用法,分别是:扩展运算符、剩余运算符...

    2 个月前
  • 解决 Enzyme 测试 React Native 组件时动画无法渲染的问题

    在开发 React Native 应用时,我们经常需要使用 Enzyme 来测试组件。然而,当我们测试涉及到动画的组件时,我们可能会遇到一些问题:动画无法渲染,导致测试失败。

    2 个月前
  • 使用 React Router 打造复杂而强大的 SPA 应用

    随着 Web 技术的不断发展,单页应用(Single Page Application,SPA)已经成为了现代 Web 应用的主流。SPA 通过异步加载数据和动态更新页面,提供了更快速、更流畅的用户体...

    2 个月前
  • AngularJS 中如何使用 ng-repeat 中的 filter 来过滤数据

    在 AngularJS 中,ng-repeat 指令是用于循环遍历数组或对象并生成 HTML 元素的常用指令。而 ng-repeat 指令中的 filter 属性则是用于过滤数据的功能。

    2 个月前
  • 如何在 Chai 中验证 Promise.all

    如何在 Chai 中验证 Promise.all 在前端开发中,Promise.all 是一个非常常用的功能,它可以让我们在多个异步操作完成后再执行一些操作,这个功能在实际开发中非常实用。

    2 个月前
  • Mongoose 实现数据批量更新的方式详解

    前言 在前端开发中,经常会涉及到对数据库中的数据进行批量更新的操作。而 Mongoose 是一款 Node.js 平台下的 MongoDB 对象模型工具,它提供了一种方便的方式来操作 MongoDB ...

    2 个月前
  • 在使用 lit-element 的时候,如何解决麻烦的 Shadow DOM 的变量传递问题

    前言 在使用 Web Components 的时候,我们通常会使用 Shadow DOM 来实现封装和样式隔离。然而,Shadow DOM 的封闭性也带来了一些挑战,其中之一就是变量传递问题。

    2 个月前
  • Tailwind CSS 如何实现动态换肤?

    随着互联网的发展,越来越多的网站和应用开始支持动态换肤功能。动态换肤不仅可以提升用户体验,还可以让用户在不同的环境下选择适合自己的主题,增加用户黏性和满意度。本文将介绍如何使用 Tailwind CS...

    2 个月前
  • 如何在 Less 中使用字符串操作函数?

    在前端开发中,样式表是不可或缺的一部分。而 Less 是一种动态样式语言,它是 CSS 的一种扩展。在 Less 中,我们可以使用字符串操作函数来处理字符串,这些函数可以帮助我们更加方便地操作字符串,...

    2 个月前

相关推荐

    暂无文章