使用nodejs注册接口逻辑处理会比较复杂,直接通过express或者koa能够简化开发流程,这里记录用koa来搭建nodejs项目并注册接口,对koa不太熟悉的话可以参考这一篇。让nodejs开启服务更简单--koa篇

项目结构

项目整体结构如下,将不同功能的文件按模块划分,使得代码逻辑更为清晰

node_modules      // 安装的包
src // 自己编码的部分
app // 注册的app
constants // 定义常量
controller // 注册接口所使用到的方法
middleware // 处理数据的中间件
router // 路由
service // 定义sql语句
utils // 处理数据的方法
main.js // 入口
.env // 放到环境变量的配置文件
package-lock.json // 包的依赖关系
package.json // 需要安装哪些包

注册app

koa中所有的操作都需要通过注册的这个app对象来完成,先在 app/index.js 中注册并导出

const Koa = require('koa')
const app = new Koa() module.exports = app

http开启服务

src文件夹下建立 main.js文件,引入app对象,开启http服务

const app = require('./app')
const { APP_PORT } = require('./app/config')
app.listen(APP_PORT, ()=>{
console.log('开启服务啦')
})

账号密码、端口号等信息直接写在文件中是不安全的,上传或共享项目的时候容易泄露,所以保存到不影响项目的的文件当中,根目录中新增 .env 文件,使用 dotenv 将 .env 文件中的配置项注册到环境变量中

APP_PORT=8000

app文件夹中新增config.js文件用于保存配置信息,防止随意更改

const dotenv = require('dotenv')
dotenv.config(); module.exports = {
APP_PORT
} = process.env

启动 main.js就已经可以监听8000端口了,因为没有对请求做出响应,所以此时访问8000,只能返回 Not Find

注册路由

一组路由就是一组映射关系,定义路径与处理函数,如下演示注册的接口逻辑,中间件用来判断数据的正确性,控制层的函数用来进行响应

const Router = require('koa-router')
const RegisterRouter = new Router({ prefix: '/register' })
const { register } = require('../controller/register.controller')
const { verifyUser, encryptionPwd } = require('../middleware/register.middleware') RegisterRouter.post('/', verifyUser, encryptionPwd, register)
module.exports = RegisterRouter

中间件

判断是否传入了用户名和密码以及是否已注册,对传入的隐私数据进行加密

const crypto = require('crypto')
const { hasUser } = require('../service/register.service')
const { USER_ALREADY_EXISTS,
  NAME_OR_PASSWORD_REQUIRED } = require('../constants/error-types') class RegisterMiddleWare {
  async verifyUser(ctx, next) {
    const { name, password } = ctx.request.body
    if (!name || !password) {
      const error = new Error(NAME_OR_PASSWORD_REQUIRED)
      return ctx.app.emit('error', error, ctx)
    }
    let users = await hasUser(name)
    if (users) {
      const error = new Error(USER_ALREADY_EXISTS)
      return ctx.app.emit('error', error, ctx)
    }
    await next()
  }   async encryptionPwd(ctx, next) {
    const { password } = ctx.request.body
    const md5 = crypto.createHash('md5')
    const pwd = md5.update(password).digest('hex')
    ctx.request.body.password = pwd
    await next()
  }
} module.exports = new RegisterMiddleWare()

与数据库建立连接

创建表结构

CREATE TABLE IF NOT EXISTS `user`(
id INT PRIMARY KEY AUTO_INCREMENT,
name varchar(50) NOT NULL UNIQUE,
password varchar(200) NOT NULL,
createAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updateAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

service/register.service.js 中定义插入数据库的方法

const connection = require('../app/database')
class RegisterService {   async hasUser(name) {
    const statement = `SELECT * FROM user WHERE name = ?`
    try {
      const [result] = await connection.execute(statement, [name])
      return result.length
    } catch (error) {
      console.log('LoginService-hasUser', error)
    }
  }   async insertUser(name, password) {
    const statement = `INSERT INTO user(name, password) VALUES(?,?)`
    try {
      const [result] = await connection.execute(statement, [name, password])
      return result
    } catch (error) {
      console.log('LoginService-insertUser', error)
    }
  }
} module.exports = new RegisterService()

很多地方都需要用到与数据库的连接,所以在 app/databse.js 中统一建立连接池

const mysql = require('mysql2')
const { MYSQL_HOST,
  MYSQL_PORT,
  MYSQL_DATABASE,
  MYSQL_USER,
  MYSQL_PASSWORD, } = require('./config')
const connection = mysql.createPool({
  database: MYSQL_DATABASE,
  host: MYSQL_HOST,
  port: MYSQL_PORT,
  user: MYSQL_USER,
  password: MYSQL_PASSWORD
})
connection.getConnection((error, conn)=>{
  conn.connect((err)=>{
    console.log(error, err)
  })
})
module.exports = connection.promise()

数据库的账号密码直接硬编码写在代码中会存在问题,同样的写到 .env 文件中,通过config.js 导出

// .env
MYSQL_HOST=localhost
MYSQL_PORT=3306
MYSQL_DATABASE=mall
MYSQL_USER=root
MYSQL_PASSWORD=123456
APP_PORT=8000
// config.js
const dotenv = require('dotenv')
dotenv.config()
module.exports = {
  APP_PORT,
  MYSQL_HOST,
  MYSQL_PORT,
  MYSQL_DATABASE,
  MYSQL_USER,
  MYSQL_PASSWORD,
} = process.env

捕获错误

当注册账号时,用户已注册或者密码不符合规范需要返回错误信息,在 constants/error-types 中定义常见的错误信息

const USER_ALREADY_EXISTS = 'user_already_exists'
const NAME_OR_PASSWORD_REQUIRED = 'name_or_password_required'
module.exports = {
  USER_ALREADY_EXISTS,
  NAME_OR_PASSWORD_REQUIRED
}

app/error-handle.js 中对错误信息进行判断

const {
  USER_ALREADY_EXISTS
} = require('../constants/error-types')
const errorHandle = (error, ctx) => {
  let code = 200
  let message = ''
  switch (error.message) {
    case USER_ALREADY_EXISTS:
      message = '该用户已存在'
      break;
  }
  ctx.status = code
  ctx.body = message
}
module.exports = errorHandle

app/index.js 引入路由定义的接口,获取post请求传递的参数,并绑定错误的处理方式

const Koa = require('koa')
const app = new Koa()
const bodyParser = require('koa-bodyparser')
const LoginRouter = require('../router/register.router')
const errorHandle = require('./error-handle')
app.use(bodyParser())
app.use(LoginRouter.routes())
app.use(LoginRouter.allowedMethods())
app.on('error', errorHandle)
module.exports = app

进行响应

在controller/register.controller.js中定义对应的处理方法

const { insertUser } = require('../service/register.service')
class RegisterController {
  async register(ctx, next) {
    const { name, password } = ctx.request.body
    const result = await insertUser(name, password)
    ctx.body = result
  }
}
module.exports = new RegisterController()

到这里为止,我们就可以对接口进行访问啦

以上就是注册一个接口的完整流程,不同接口可能需要通过不同的中间件去处理,比如登录接口需要验证密码,派发token,其他和用户权限有关的接口需要验证token。

以下还有几篇相关笔记可供参考

jwt实现token鉴权(nodejs koa

如何通过cookie、session鉴权(nodejs/koa)

超详细的mysql总结(DQL)

超详细的mysql总结(基本概念、DDL、DML)

nodejs中如何使用http创建一个服务

koa搭建nodejs项目并注册接口的更多相关文章

  1. Express搭建NodeJS项目

    1.安装Node.js: 2.安装npm; 3.安装Express; 在本例中默认全局安装express 安装express生成器 如果没有安装express-generator或安装路径不对,会报以 ...

  2. koa 项目实战(四)注册接口和调试工具(postman)

    1.安装模块 npm install koa-bodyparser --save npm install bcryptjs --save 2.引入模块 根目录/app.js const bodyPar ...

  3. Django商城项目笔记No.6用户部分-注册接口-短信验证码实现celery异步

    Django商城项目笔记No.4用户部分-注册接口-短信验证码实现celery异步 接上一篇,如何解决前后端请求跨域问题? 首先想一下,为什么图片验证码请求的也是后端的api.meiduo.site: ...

  4. 在vue-cli搭建的项目中增加后台mock接口

    用vue-cli搭建一个前端开发环境确实是极其方便,在写前端代码肯定也是少不了需要调用后台提供的业务接口进行前后端交互,特别在敏捷开发中,前后端都要提前确定业务接口并进行打桩,在开发过程中基本是没有现 ...

  5. Django商城项目笔记No.9用户部分-注册接口签发JWTtoken

    Django商城项目笔记No.9用户部分-注册接口签发JWTtoken 我们在验证完用户的身份后(检验用户名和密码),需要向用户签发JWT,在需要用到用户身份信息的时候,还需核验用户的JWT. 关于签 ...

  6. Django商城项目笔记No.8用户部分-注册接口实现

    Django商城项目笔记No.8用户部分-注册接口实现 users的view.py中增加如下代码 class RegisterUserView(CreateAPIView): "" ...

  7. Django商城项目笔记No.7用户部分-注册接口-判断用户名和手机号是否存在

    Django商城项目笔记No.7用户部分-注册接口-判断用户名和手机号是否存在 判断用户名是否存在 后端视图代码实现,在users/view.py里编写如下代码 class UsernameCount ...

  8. Django商城项目笔记No.5用户部分-注册接口-短信验证码

    Django商城项目笔记No.4用户部分-注册接口-短信验证码 短信验证码也保存在redis里(sms_code_15101234567) 在views中新增SMSCodeView类视图,并且写出步骤 ...

  9. Django商城项目笔记No.4用户部分-注册接口-图片验证码

    Django商城项目笔记No.4用户部分-注册接口-图片验证码 1.首先分析注册业务接口 1.1.分析可得,至少这么几个接口 图片验证码 短信验证码 用户名是否存在 手机号是否存在 整体注册接口 图片 ...

  10. 在vue-cli搭建的项目中在后台mock接口中支持req.body和req.cookies

    在<vue-cli搭建的项目中增加后台mock接口>中实现了后台mock,但是前端post的t数据都要在mock的后台接口中使用req的接收数据事件获取http协议body中的数据. re ...

随机推荐

  1. 2021-08-02:按公因数计算最大组件大小。给定一个由不同正整数的组成的非空数组 A,考虑下面的图:有 A.length 个节点,按从 A[0] 到 A[A.length - 1] 标记;只有当

    2021-08-02:按公因数计算最大组件大小.给定一个由不同正整数的组成的非空数组 A,考虑下面的图:有 A.length 个节点,按从 A[0] 到 A[A.length - 1] 标记:只有当 ...

  2. Python异步编程之web框架异步vs同步 无IO任务压测对比

    前言 在python编程中,通过协程实现的异步编程号称能够提高IO密集型任务的并发量.本系列比较web服务器同步框架和异步框架的性能差异,包括无IO接口和常见IO操作,如文件.mysql.redis等 ...

  3. 发布 markdown 小功能:指定图片尺寸

    之前园子的 markdown 功能多年落后,这两年我们正在努力赶上. 今天发布一个 markdown 小功能,可以通过 markdown 语法指定图片尺寸. 指定宽度 =200x ![](https: ...

  4. ODOO13之二 Odoo 13开发之开发环境准备

    在更深入了解 Odoo 开发之前,我们应配置好开发环境并学习相关的基础管理任务.本文中,我们将学习创建 Odoo 应用所需用到的工具和环境配置.这里采用 Ubuntu 系统来作为开发服务器实例的主机, ...

  5. Python连接es笔记二之查询方式汇总

    本文首发于公众号:Hunter后端 原文链接:Python连接es笔记二之查询方式汇总 上一节除了介绍使用 Python 连接 es,还有最简单的 query() 方法,这一节介绍一下几种其他的查询方 ...

  6. DevOps| 研发效能和PMO如何合作共赢?

    项目经理(PMO)对于大组织.跨团队高效协同有着不可替代的作用.跳出组织架构的束缚,横向推动公司级别的大项目向前推进,跟进进展和拿到结果,PMO的小伙伴有着独特的优势. 我之前写过小团队如何高效协作的 ...

  7. Python3.9安装

    一.安装python3.9 链接:https://pan.baidu.com/s/1mDkgKt2KSoMrKVxesb76Pg?pwd=ma4n 提取码:ma4n --来自百度网盘超级会员V4的分享 ...

  8. selenium4-获取页面元素相关信息

    本小节我们简单说下如何使用selenium4-获取页面元素相关信息,以及获取页面元素的相关信息后可以做什么. 获取页面元素的主要目的:(1)执行完步骤后进行断言:(2)获取前一步骤的响应结果作为后续步 ...

  9. Python与TensorFlow:如何高效地构建和训练机器学习模型

    目录 标题:<Python 与 TensorFlow:如何高效地构建和训练机器学习模型> 一.引言 随着人工智能的快速发展,机器学习作为其中的一个重要分支,受到了越来越多的关注和应用.而P ...

  10. 信创优选,国产开源,Solon v2.3.6 发布

    Solon 是什么开源项目? 一个,Java 新的生态型应用开发框架.它从零开始构建,有自己的标准规范与开放生态(历时五年,已有全球第二级别的生态).与其他框架相比,它解决了两个重要的痛点:启动慢,费 ...