欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Nodejs博客开发笔记

程序员文章站 2022-04-01 19:08:59
Nodejs博客开发笔记(持续更新)接口设计描述接口方法url参数备注获取博客列表/api/blog/listgetauthor 作者,keyword 搜索关键字参数为空的话,则不进行查询过滤获取一篇博客的内容/api/blog/detailgetid新增一篇博客/api/blog/newpostpost中有新增的信息更新一篇博客/api/blog/updatepostidpostData中有更新的内容删除一篇博客/ap...

Nodejs博客开发笔记(持续更新)

接口设计

描述 接口 方法 url参数 备注
获取博客列表 /api/blog/list get author 作者,keyword 搜索关键字 参数为空的话,则不进行查询过滤
获取一篇博客的内容 /api/blog/detail get id
新增一篇博客 /api/blog/new post post中有新增的信息
更新一篇博客 /api/blog/update post id postData中有更新的内容
删除一篇博客 /api/blog/del post id
登录 /api/user/login post postData中有用户名和密码

基本目录结构

|-- bin

​   |-- www.js  ---  服务启动文件

|-- src

​	|-- controller

​		|-- blog.js  ---  数据文件

​	|-- model

​		|-- resModel.js  ---  模型文件

​	|-- router

​		|-- blog.js  ---  存放 blog 目录下的路由

​		|-- user.js  ---  存放 user 目录下的路由

|-- app.js  ---  处理路由的文件

|-- package.json  ---  包管理文件

博客搭建过程

【梦初】

把服务跑起来

www.js

const http = require("http");
const serverHandle = require("../app");
const port = 3000;
const server = http.createServer(serverHandle);

server.listen(port, () => {
  console.log(`服务启动成功 --- ${port}`);
});

serverHandle 是分离出去的回调函数

【梦入】

把 serverHandle 导出去

app.js

const serverHandle = (req, res) => {
  // 设置返回格式 JSON
  res.setHeader("Content-Type", "application/json");
  res.end("Hello Blog!")
};

module.exports = serverHandle;

现在 127.0.0.1:3000 就能正常启动了

【梦时】

我需要写路由,怎么办呢?于是乎我便把 blog 和 user 两个目录下的路由分别写到不同的 js 文件中,然后导出供 app.js 文件进行路由处理

blog.js

const handleBlogRouter = (req, res) => {
  const method = req.method; // GET POST
  const url = req.url;
  // 获取路由地址
  const path = url.split("?")[0];

  // 获取博客列表
  if (method == "GET" && path == "/api/blog/list") {
    return {
      msg: "这是获取博客列表的接口",
    };
  }

  // 获取博客详情
  if (method == "GET" && path == "/api/blog/detail") {
    return {
      msg: "这是获取博客详情的接口",
    };
  }

  // 新建一篇博客
  if (method == "POST" && path == "/api/blog/new") {
    return {
      msg: "这是新建博客的接口",
    };
  }

  // 更新一篇博客
  if (method == "POST" && path == "/api/blog/update") {
    return {
      msg: "这是更新博客的接口",
    };
  }
};

module.exports = handleBlogRouter;

user.js

const handleUserRouter = (req, res) => {
  const method = req.method; // GET POST
  const url = req.url;
  // 获取路由地址
  const path = url.split("?")[0];

  // 登录
  if (method == "POST" && path == "/api/user/login") {
    return {
      msg: "这是用户登录的接口",
    };
  }
};

module.exports = handleUserRouter;

【梦境】

但是写好路由之后怎么使用它呢?这就需要通过 app.js 来处理路由了,我们通常会在处理路由时,先给它设置 JSON 的返回格式,然后处理时需要以字符串的形式响应给前端,具体如下

app.js

// 导入 blog 路由文件
const handleBlogRouter = require("./src/router/blog");
// 导入 user 路由文件
const handleUserRouter = require("./src/router/user");

const serverHandle = (req, res) => {
  // 设置返回格式 JSON
  res.setHeader("Content-Type", "application/json");

  // 处理 blog 路由
  const blogData = handleBlogRouter(req, res);
  if (blogData) {
    // 把 JSON 类型的数据先转换为字符串,再响应给前端
    res.end(JSON.stringify(blogData));
    // 最后需要返回
    return;
  }

  // 处理 user 路由
  const userData = handleUserRouter(req, res);
  if (userData) {
    // 把 JSON 类型的数据先转换为字符串,再响应给前端
    res.end(JSON.stringify(userData));
    // 最后需要返回
    return;
  }

  // 未命中路由,返回 404
  res.writeHead(404, { "Content-Type": "text/plain" });
  res.write("404 Not Found\n");
  res.end();
};

module.exports = serverHandle;

现在我们已经可以通过 http://127.0.0.1:3000/api/blog/list 来正常的访问了

【梦遇】

虽然已经可以正常的访问了,但是我们可以发现, blog.js user.js 中是有重复的代码的,这就需要通过路由设计来优化代码了

app.js 中处理它们重复的代码

const url = req.url;
req.path = url.split("?")[0];

app.js

// 导入 blog 路由文件
const handleBlogRouter = require("./src/router/blog");
// 导入 user 路由文件
const handleUserRouter = require("./src/router/user");

const serverHandle = (req, res) => {
  // 设置返回格式 JSON
  res.setHeader("Content-Type", "application/json");

  const url = req.url;
  req.path = url.split("?")[0];
  // 处理 blog 路由
  const blogData = handleBlogRouter(req, res);
  if (blogData) {
    // 把 JSON 类型的数据先转换为字符串,再响应给前端
    res.end(JSON.stringify(blogData));
    // 最后需要返回
    return;
  }

  // 处理 user 路由
  const userData = handleUserRouter(req, res);
  if (userData) {
    // 把 JSON 类型的数据先转换为字符串,再响应给前端
    res.end(JSON.stringify(userData));
    // 最后需要返回
    return;
  }

  // 未命中路由,返回 404
  res.writeHead(404, { "Content-Type": "text/plain" });
  res.write("404 Not Found\n");
  res.end();
};

module.exports = serverHandle;

blog.js user.js 文件中就得写成 req.path

blog.js

const handleBlogRouter = (req, res) => {
  // 获取博客列表
  if (req.method == "GET" && req.path == "/api/blog/list") {
    return {
      msg: "这是获取博客列表的接口",
    };
  }

  // 获取博客详情
  if (req.method == "GET" && req.path == "/api/blog/detail") {
    return {
      msg: "这是获取博客详情的接口",
    };
  }

  // 新建一篇博客
  if (req.method == "POST" && req.path == "/api/blog/new") {
    return {
      msg: "这是新建博客的接口",
    };
  }

  // 更新一篇博客
  if (req.method == "POST" && req.path == "/api/blog/update") {
    return {
      msg: "这是更新博客的接口",
    };
  }
};

module.exports = handleBlogRouter;

user.js

const handleUserRouter = (req, res) => {
  // 登录
  if (req.method == "POST" && req.path == "/api/user/login") {
    return {
      msg: "这是用户登录的接口",
    };
  }
};

module.exports = handleUserRouter;

【梦醒】

现在虽然能返回一些内容了,但是我们需要返回一些动态的数据,数据是由 router/blog.js 文件中的路由返回的,同样的道理,把数据单独做成一个文件

controller 目录下新建一个 blog.js 文件

controller/blog.js

const getList = (author, keyword) => {
  // 先返回假数据(格式是正确的)
  return [
    {
      id: 1,
      title: "标题A",
      content: "内容A",
      createTime: 1601305438637,
      author: "张三",
    },
    {
      id: 1,
      title: "标题B",
      content: "内容B",
      createTime: 1601305527630,
      author: "李四",
    },
  ];
};

module.exports = {
  getList,
};

这时我们就可以在 router/blog.js 文件中去使用这个数据文件中的数据了

// 导入 getList 数据文件
const { getList } = require("../controller/blog");

想要获取到用户提交的数据,需要解析 query,获取到 query 对象

首先引入 querystring,然后再使用 querystring.parse 对url进行解析

// 引入querystring
const querystring = require("querystring");
// 解析 query
req.query = querystring.parse(url.split("?")[1]);

app.js

// 导入 blog 路由文件
const handleBlogRouter = require("./src/router/blog");
// 导入 user 路由文件
const handleUserRouter = require("./src/router/user");

// 引入querystring
const querystring = require("querystring");

const serverHandle = (req, res) => {
  // 设置返回格式 JSON
  res.setHeader("Content-Type", "application/json");

  const url = req.url;
  req.path = url.split("?")[0];

  // 解析 query
  req.query = querystring.parse(url.split("?")[1]);

  // 处理 blog 路由
  const blogData = handleBlogRouter(req, res);
  if (blogData) {
    // 把 JSON 类型的数据先转换为字符串,再响应给前端
    res.end(JSON.stringify(blogData));
    // 最后需要返回
    return;
  }

  // 处理 user 路由
  const userData = handleUserRouter(req, res);
  if (userData) {
    // 把 JSON 类型的数据先转换为字符串,再响应给前端
    res.end(JSON.stringify(userData));
    // 最后需要返回
    return;
  }

  // 未命中路由,返回 404
  res.writeHead(404, { "Content-Type": "text/plain" });
  res.write("404 Not Found\n");
  res.end();
};

module.exports = serverHandle;

现在我们可以在 router/blog.js 文件中调用 getList 函数,来获取到需要返回的数据了

// 获取 query 中的 anthor ,如果没有则为空字符串
const author = req.query.author || "";
// 获取 query 中的 keyword ,如果没有则为空字符串
const keyword = req.query.keyword || "";
// 调用 getList 函数
const listData = getList(author, keyword);

但是又想到我们不能直接把这个数据直接返回给前端,我们需要返回给前端的只是需要一些 code 啊,message 、data 之类的东西

所以需要创建模型文件,把需要返回的数据用类来封装一下

resModel.js

class BaseModel {
  constructor(data, message) {
    if (typeof data === "string") {
      this.message = data;
      data = null;
      message = null;
    }
    if (data) {
      this.data = data;
    }
    if (message) {
      this.message = message;
    }
  }
}

class SuccessModel extends BaseModel {
  constructor(data, message) {
    super(data, message);
    this.errno = 0;
  }
}

class ErrorModel extends BaseModel {
  constructor(data, message) {
    super(data, message);
    this.errno = -1;
  }
}

module.exports = {
  SuccessModel,
  ErrorModel,
};

router/blog.js 文件中导入数据模型

// 导入数据模型
const { SuccessModel, ErrorModel } = require("../model/resModel");

返回一个 SuccessModel 对象

// 返回一个 SuccessModel 对象
return new SuccessModel(listData);

意思就是说在 SuccessModel 中只传入一个 data 数据,当执行 SuccessModel 类时,会把 listData 的值赋给 this.data 类本身,并且 SuccessModel 自带 error为0

当我在浏览器输入 http://127.0.0.1:3000/api/blog/list 的时候,页面会返回以下内容

{
    "data":[
        {
            "id":1,
            "title":"标题A",
            "content":"内容A",
            "createTime":1601305438637,
            "author":"张三"
        },
        {
            "id":1,
            "title":"标题B",
            "content":"内容B",
            "createTime":1601305527630,
            "author":"李四"
        }
    ],
    "errno":0
}

【梦结】

来总结一下

代码是怎么运行的?

  • 第一层 – www.js

    • 开启服务
  • 第二层 – app.js

    • 设置返回格式 JSON
    • 解析 query
    • 处理 blog 路由
    • 处理 user 路由
    • 未命中路由,返回 404
  • 第三层 – router/blog.js

    • 路由文件
  • 第四层 – controller/blog.js

    • 最关心数据的一层
    • 用来存放数据

欲知后事如何,请看下集~

本文地址:https://blog.csdn.net/Cool_breeze_/article/details/108860336

相关标签: Nodejs