likes
comments
collection
share

解决学习与开发Node接口无从下手的难题:一步步构建基于Node和Express的API应用

作者站长头像
站长
· 阅读数 18

如果你对学习和开发Node接口感到困惑,我将帮助你解决这个问题。

简介:

这篇文章是关于学习和开发Node.js接口的新手指南。文章首先介绍了使用Node.js和Express框架进行开发的经典技术。文章描述了一个示例项目的文件结构,包括主文件(app.js)、模型文件夹(models)、控制器文件夹(controllers)和路由文件夹(routes)之间的关系。

这是一份简单明了的Node.js接口开发入门指南,通过介绍项目结构、搭建步骤和示例案例,帮助你快速入门并理解Node.js接口开发的基本原理和技术。

一、开始

结构

这个简单的层级结构图显示了主文件app.js、模型文件夹models、控制器文件夹controllers和路由文件夹routes之间的关系。其中,假设:模型文件夹中包含a.js,控制器文件夹中包含aController.js,而路由文件夹中包含a.js

    .
    ├── controller                      处理中心文件,负责路由及数据库的具体操作
    │   ├── a目录
    │   │   └── a.js     
    │   ├── b目录
    │       └── b.js                
    ├── models                          模型(数据库)文件
    │   ├── a目录
    │   │   └── a1.js    
    │   │   └── a2.js            
    │   ├── b目录
    │       └── b.js                
    ├── mongodb                         mongodb数据库的连接文件
    │   └── db.js
    ├── routes                          路由配置文件
    │   ├── arouter.js                   
    │   ├── brouter.js     
    ├── app.js                          主文件     

这只是一个示例层级结构图,你可以根据项目需求进行调整和扩展。

流程

解决学习与开发Node接口无从下手的难题:一步步构建基于Node和Express的API应用

  1. MongoDB(数据库):MongoDB是一个非关系型数据库,用于存储和管理数据。它以文档的形式存储数据,具有灵活的模式和可扩展性。可以使用MongoDB存储应用程序的数据。
  2. Mongoose(ODM库):Mongoose是一个Node.js的对象数据建模(ODM)库,它提供了一种与MongoDB进行交互的简单方式。Mongoose允许您在Node.js中定义模型和模式,并提供了一些功能,如数据验证、中间件和查询构建器。
  3. 模型(models):在使用Mongoose时,您需要定义模型来表示MongoDB中的集合。模型定义了文档的结构和行为,包括字段、验证规则和数据库操作方法。
  4. 控制器(controllers):控制器是处理请求并生成响应的组件。在Node.js中,控制器负责处理从路由接收到的请求,执行逻辑操作(如数据读取、数据处理等),然后生成相应的响应(res.send)。
  5. 路由(routes):路由定义了URL路径与控制器方法之间的映射关系
  6. API(应用程序接口):API代表应用程序接口,它定义了应用程序向外部提供的服务和功能。通过定义路由和关联的控制器方法,您可以创建API,使其他应用程序或客户端能够使用您的应用程序的功能。

使用MongoDB作为数据库,并使用Mongoose作为与MongoDB进行交互的ODM库。您将定义模型来表示数据结构,并编写控制器来处理请求和生成响应。通过定义路由,您将映射URL路径到相应的控制器方法,从而创建一个API,使其他应用程序能够访问和使用您的应用程序的功能。

二、搭建

搭建一个简单的框架。

首先,通过运行npm init命令初始化项目并生成package.json文件。

然后,通过安装Express和nodemon等包来搭建项目。

  • Express是一个流行的Node.js Web应用程序框架,用于构建Web应用程序和API。
  • nodemon是一个工具,用于在开发过程中监视文件的变化并自动重启应用。

另外,还介绍了使用Mongoose进行MongoDB数据库操作的步骤,包括安装Mongoose和连接数据库。

搭建package.json

初始化项目

    npm init

获得项目运行的package.json

安装express

引入

    cnpm i express

效果

Express 是一个流行的 Node.js Web 应用程序框架,用于构建 Web 应用程序和 API。

安装nodemon

引入:

    cnpm i nodemon

作用:

用于在开发过程中监视文件的变化并自动重启应用。

使用:

    "scripts": {
        "dev": "nodemon app.js"
     },

安装mongoose

Mongoose是NodeJS的驱动,不能作为其他语言的驱动。

引入:

    cnpm i mongoose

作用:

连接到 MongoDB、定义模型和模式、执行数据库操作、数据验证和转换、中间件支持等

简单使用:

    // 替换为实际的 MongoDB 连接字符串
    const mongodbConfigUrl = 'mongodb://localhost:27017/mydatabase'; 
    
    mongoose.connect(mongodbConfigUrl, {
      useNewUrlParser: true,
      useUnifiedTopology: true,
      useCreateIndex: true,
       // ....
    }).then(() => {
      console.log('连接成功');
    }).catch((error) => {
      console.error('连接失败:', error);
    });
    

三、案例

文章提供了一个示例案例,包括主文件(app.js)、模型文件(models)、控制器文件(controllers)和路由文件(routes)的代码示例。主文件是整个应用程序的入口点,负责创建Express应用程序实例、配置中间件、连接数据库、定义路由等。模型文件定义了MongoDB中集合的模型和模式。控制器文件是处理请求并生成响应的组件,负责执行逻辑操作和生成响应。路由文件定义了URL路径与控制器方法之间的映射关系。

app.js主文件

整个应用程序的入口点和核心文件。

承载的一些常见功能:创建 Express 应用程序实例、配置中间件、连接数据库、定义路由、错误处理、监听端口等

它是构建和运行应用程序的核心文件

    const express = require("express");
    const router = require("./routes/index.js");
    const db = require("./mongodb/db.js");
    const app = express();
    
    const config = {
      port: 8002,
      url: 'mongodb://localhost:27017/xxx',
    }
    
    // 給router路由送去app参数对象
    router(app);
    
    db(config);
    
    app.listen(config.port, () => {
      console.log(`${config.port}端口:监听打开了`);
    })

models

假设我们有一个user的对象

mongodb的数据存储内容为

    /** 
    * Paste one or more documents here
    */
    {
      "id": 1,
      "user_name": "maotou",
      "password": "123456",
      "city": "上海",
      "create_time": "2023-07-04 13:36",
      "avatar": "16aaf980b9a39581.jpg",
      "__v": 0
    }

在使用Mongoose时,您需要定义模型来表示MongoDB中的集合

    const mongoose = require("mongoose");
    
    const Schema = mongoose.Schema;
    
    const userSchema = new Schema({
      id: Number,
      user_name: String,
      password: String,
      city: String,
      create_time: String,
      avatar: { type: String, default: 'default.jpg' }
    })
    
    userSchema.index({ id: 1 });
    
    const User = mongoose.model('User', userSchema);
    
    module.exports = User;

controller

控制器是处理请求并生成响应的组件。在Node.js中,控制器负责处理从路由接收到的请求,执行逻辑操作(如数据读取、数据处理、调用其他模块等),然后生成相应的响应(res.send)。

简单说就是:

你要拿数据库的数据,做什么用,就写什么代码。

    const UserModel = require("../models/user.js")
    
    class User {
    
      constructor() {
    
      }
    
      async search (req, res, next) {
        const { user_name } = req.query;
        console.log("user_name", user_name);
        try {
          const user = await UserModel.findOne({}, "-_id -__v");
          res.send(user)
        } catch (err) {
          console.log(err);
        }
      }
    }
    
    module.exports = new User();

routes

路由定义了URL路径与控制器方法之间的映射关系

练controller的数据都处理完成了,那么就要考虑传递出去了

    const express = require("express");
    const User = require("../controller/user")
    
    const router = express.Router();
    
    router.get('/search', User.search);
    
    module.exports = router;

定义一个集中导出

    import user from "./user.js";
    
    // 接受 app.js 传递来的 app
    module.exports = (app) => {
      app.use(user);
    
    }

mongodb连接

用于web引用与mongodb的连接

    const mongoose = require("mongoose")
    
    module.exports = (config) => {
    
      mongoose.connect(config.url, {
        useNewUrlParser: true,
        useUnifiedTopology: true
      });
    
      mongoose.Promise = global.Promise;
    
      const db = mongoose.connection;
    
      db.once('open', () => {
        console.log('连接数据库成功');
      })
    
      db.on('error', (error) => {
        console.error('Error in MongoDb connection: ' + error);
        mongoose.disconnect();
      });
    
      db.on('close', () => {
        console.log('数据库断开,重新连接数据库');
        mongoose.connect(config.url, { server: { auto_reconnect: true } });
      });
    };

效果

本地测试接口api:http://localhost:8001/search?user_name=maotou

响应数据:

    user_name maotou
    
    实时响应:
    {
        "avatar": "default.jpg",
        "username": "maotou",
        "password": "IEdv0tn+Q5r4w95+2J9EDg==",
        "user_id": 1
    }

四、问答

1、models中的代码

adminSchema.index({id: 1})

这行代码创建了一个名为 id 的索引,以加快根据 id 字段进行查询的速度。

2、mongodb中的代码

mongoose.Promise = global.Promise

在早期的版本中,Mongoose 使用了自己的 Promise 实现。然而,自 ECMAScript 2015(ES6)起,JavaScript 提供了原生的 Promise 对象作为异步操作的标准机制。为了兼容性和一致性,Mongoose 提供了选项来使用全局的 Promise 实现,即全局环境中可用的 Promise 对象。

通过将 mongoose.Promise 设置为 global.Promise,您将使用全局环境中的 Promise 实现,即全局的 Promise 对象。这样做可以确保在 Mongoose 的异步操作中使用标准的 Promise 语法和功能。

3、希望使用ES6的导入导出

需要安装使用babel来解析

可以先尝试修改package.json文件 加入以下代码

  "type": "module",

4、req,res,next

在 Express 中,req 是表示请求对象的参数,res 是表示响应对象的参数,next 是表示下一个中间件或路由处理函数的参数。

  • req 对象包含了客户端发送的请求信息,例如请求头、请求参数、请求体等。
  • res 对象用于设置服务器响应的信息,例如响应头、响应状态码、响应数据等。
  • next 参数是一个函数,用于将请求传递给下一个中间件或路由处理函数,类似于链式调用中的"下一个"。

通过 req.headers 可以访问请求头的信息,而通过 res.header 可以设置响应头的信息。通过使用这些信息,可以实现自定义的请求头和响应头配置,以满足特定的需求。

5、post请求使用json文件传递

app.js中开启即可

    app.use(express.json());

使用接收

    async login (req, res, next) {
      const { username, password } = req.body;
      console.log(username, password)
    }

6、解决跨域访问的问题

设置app处理请求的中间件

任何请求就会进来这个中间件,判断来源、请求类型等有无问题。

app.all('*', (req, res, next) => {
  const { origin, Origin, referer, Referer } = req.headers;
  const allowOrigin = origin || Origin || referer || Referer || '*';
	res.header("Access-Control-Allow-Origin", allowOrigin);
	res.header("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With");
	res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
  res.header("Access-Control-Allow-Credentials", true); //可以带cookies
	res.header("X-Powered-By", 'Express');
	if (req.method == 'OPTIONS') {
  	res.sendStatus(200);
	} else {
    next();
	}
});

这段代码的作用是解决跨域访问的问题,允许来自不同域的请求访问你的服务器资源,并设置必要的 CORS 响应头。

设置响应头 Access-Control-Allow-Origin,将允许访问的域名作为值。这样就允许指定的域名发送跨域请求。

设置响应头 X-Powered-By,表示使用 Express 框架处理请求。

如果请求方法是 OPTIONS,表示这是一个预检请求(preflight request),则返回状态码 200 表示请求成功。预检请求是浏览器在发送真正的跨域请求之前发送的一种探测请求,用于检查服务器是否允许实际请求的跨域访问。

如果不是预检请求,调用 next() 方法将请求传递给下一个中间件或路由处理函数


以后有问题再补充🐅

代码自取

点击图标,跳转github

解决学习与开发Node接口无从下手的难题:一步步构建基于Node和Express的API应用