前端进阶全栈入门级教程nodeJs博客开发(一)搭建环境与路由

Posted MmM豆

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端进阶全栈入门级教程nodeJs博客开发(一)搭建环境与路由相关的知识,希望对你有一定的参考价值。

阅读本篇文章时候,需要前端有一定基础后,想要进阶全栈,或者了解后端工作方式阅读,能更好的提高,前后分离对接的理解,本篇只会,概况的带领操作一遍,后端开发。简单易懂。

文章目录

一、搭建开发环境

tips 以下注释 // 省略。。。。 均为省略未修改部分

我们先创建文件夹nativBlog

然后使用 npm init -y 初始化一个项目

  1. 安装nodemon 自动重启node

    npm i nodemon -D
    
  2. 安装cross-env 控制开发环境

    npm i cross-env -D
    

按照下列创建并修改文件,搭建一个基础的nodeSever,并返回一定数据

文件结构

├─app.js
├─package.json
├─src
├─bin
|  └www.js

www.js

const http = require('http')

const PORT = 8000
const serverHandle = require('../app')

const server = http.createServer(serverHandle)
server.listen(PORT)
console.log('已开启 8000端口');

app.js

const serverHandle = (req,res)=>
  // 设置返回格式 JSON
  res.setHeader('Content-type','application/json')
   //模拟一下假数据 
  const resData = 
    name:'admin',
    env:process.env.NODE_ENV
  

  res.end(
    JSON.stringify(resData)
  )


module.exports = serverHandle

添加启动命令

package.json


  "name": "native-blog",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": 
    "test": "echo \\"Error: no test specified\\" && exit 1",
    "dev": "cross-env NODE_ENV=dev nodemon ./bin/www.js",
    "prd": "cross-env NODE_ENV=production nodemon ./bin/www.js"
  ,
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": ,
  "devDependencies": 
    "cross-env": "^7.0.3",
    "nodemon": "^2.0.7"
  


运行一下

然后打开浏览器或者postman测试一下

npm run dev

二、搭建路由

路由和API的概念

API:

前端和后端、不同端(子系统)之间对接的一个术语

前端只需要知道 url(路由)是什么,传递方式和参数,不需要知道如何实现

路由:

API的一部分,

后端系统内部的一个定义,

,比如要实现一个api,需要定义一个router,controller db model等等

(一) 搭建基础路由

以下为我们需要建立的接口

我们区分blog和user2个部分建立文件

├─src
|  ├─router //处理路由
|  |   ├─blog.js
|  |   └user.js

blog.js

const  handleBlogRouter = (req,res) =>
console.log('method:',req.method);
console.log(' req.path:', req.path);

  // 获取博客列表
  if(req.method ==='GET'&&  req.path ==='/api/blog/list') 
    console.log('进入2');
    
    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:'这是更新博客列表的接口'
    
  
  // 删除博客列表
  if(req.method === 'GET'&&  req.path ==='/api/blog/del') 
    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

修改一下原本的app.js 来处理请求

const querystring = require('querystring') //引入原生模块解析get参数
const handleBlogRouter = require('./src/router/blog')
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]
  // 解析query
    req.query = querystring.parse(url.split('?')[0])
    // 处理blog路由
    const blogData= handleBlogRouter(req,res)

    if(blogData)
      res.end(
        JSON.stringify(blogData)
      )
      return
    

    // 处理user路由
    const userData= handleUserRouter(req,res)

    if(userData)
      res.end( 
        JSON.stringify(userData)
      )
      return

// 未命中路由返回404
res.writeHead(404,"COntent-type":"text/plian")
res.write("404 Not Found\\n")
res.end()


module.exports = serverHandle

通过上步,我们简单搭建了一套路由,然后用在psotman来测试一下

OK,没有问题,当然你需要每个接口都尝试一下

(二)创建controller 和model层

文件结构

├─src
|  ├─router //处理路由
|  |   ├─blog.js
|  |   └user.js
|  ├─model //建立数据模型
|  |   └resModel.js
|  ├─controller //处理业务逻辑
|  |     ├─blog.js
|  |     └user.js


分清楚一个事实,就要分清层级,router只管路由的处理,www.js只管创建sever,controller只管业务逻辑的处理

model 处理返回的数据结构

到这一步,还没连接数据库,但我们要假装模拟一下真实的数据返回

首先建立model

resModel.js

class BaseModel 
  constructor(data, message) 
      // 兼容判断是否传人2个参数
      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

其次建立controller层

先做个简单的假数据模拟、

blog.js

const getList = (author,keyword) =>
	//模拟返回的数据,用promise模拟异步数据库操作
  const promise = new Promise((resolve,reject)=>
    const data = [
      
        id:1,
        title:"标题A",
        content:"内容A",
        createTime:1600410168761,
        author:"张三"
      ,
      
        id:2,
        title:"标题B",
        content:"内容B",
        createTime:1600410221493,
        author:"李四"
      
    ]
    resolve(data)
  )
  return promise

module.exports = 
  getList

然后修改router下bolg.js的处理,修改一个接口来体验一下

blog.js

//导入controller
const getList = require('../controller/blog')
//导入model
const SuccessModel,ErrorModel = require('../model/resModel')
......省略未修改部分

// 获取博客列表
  if(req.method ==='GET'&&  req.path ==='/api/blog/list') 
    const author = "张三"
    const keyword = "标题A"
    
      const result = getList(author,keyword)
    return result.then(data =>
        return new SuccessModel(data,'请求成功')
    )
  
......省略未修改部分

app.js

...省略未修改部分

const serverHandle = (req,res)=>
...省略未修改部分
            // 处理blog路由
        const blogResult= handleBlogRouter(req,res)
        if(blogResult)
          blogResult.then(blogData =>
            if(blogData)
              res.end(
                JSON.stringify(blogData)
              )
            
          )
          return
        
        // // 处理user路由
        const userResult= handleUserRouter(req,res)
        if(userResult)
          userResult.then(userData=>
            if(userData)
              res.end(
                JSON.stringify(userData)
              )
              return
            
          )
        
...省略未修改部分

module.exports = serverHandle

修改完成后用postman来测试

测试成功,代表我们的模块规划没有问题

(三)处理post请求

前面都是用的get,对于post我们还没做任何处理,post是异步操作,所以我们需要用promise来处理一下

封装一个下面方法来处理post

// 处理post请求
const getPostData = (req) => 
  const promise = new Promise((resolve, reject) => 
    // 不是post,get请求
      if (req.method !== 'POST') 
          resolve()
          return
      
      // post请求处理, 如果返回的格式不是json 返回一个空
      if (req.headers['content-type'] !== 'application/json') 
          resolve()
          return
      
      let postData = ''
      //   post数据其实是数据流,所以我们需要监听拼接数据
      req.on('data', chunk => 
          postData += chunk.toString()
      )
      req.on('end', () => 
        // 没有数据返回一个空
          if (!postData) 
              resolve()
              return
          
          resolve(
              JSON.parse(postData)
          )
      )
  )
  return promise

然后app.js完整代码 如下,在处理路由前,先通过封装的方法处理一下post请求

const querystring = require('querystring')
const handleBlogRouter = require('./src/router/blog')
const handleUserRouter = require('./src/router/user')

// 处理post请求
const getPostData = (req) => 
  const promise = new Promise((resolve, reject) => 
    // 不是post,get请求
      if (req.method !== 'POST') 
          resolve()
          return
      
      // post请求处理, 如果返回的格式不是json 返回一个空
      if (req.headers['content-type'] !== 'application/json') 
          resolve()
          return
      
      let postData = ''
      req.on('data', chunk => 
          postData += chunk.toString()
      )
      req.on('end', () => 
        // 没有数据返回一个空
          if (!postData) 
              resolve()
              return
          
          resolve(
              JSON.parse(postData)
          )
      )
  )
  return promise


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])
    // 处理post请求
    getPostData(req).then(postData=>
          req.body = postData
            // 处理blog路由
        const blogResult= handleBlogRouter(req,res)
        if(blogResult)
          blogResult.then(blogData =>
            if(blogData)
              res.end(
                JSON.stringify(blogData)
              )
            
          )
          return
        

        // // 处理user路由
        const userResult= handleUserRouter(req,res)
        if(userResult)
          userResult.then(userData=>
            if(userData)
              res.end(
                JSON.stringify(userData)
              )
            
          )
              return
        
    
    // 未命中路由返回404
    res.writeHead(404,"COntent-type":"text/plian")
    res.write("404 Not Found\\n")
    res.end()
  )

   


module.exports = serverHandle

之后修改一个post接口来测试一下

controller

blog.js

...省略
const newBlog = (blogData = ) =>
  // blogData 包含 title content
  // 添加成功返回添加id,
    //模拟处理完成后返回数据
  const promise = new Promise((resolve,reject)=>
    const data = 
      id:3
    
    resolve(data)
  )
  return promise

module.exports = 
    ...省略
  newBlog

router

blog.js

const 
  ...省略
  newBlog = require('../controller/blog')
 ...省略

  // 新建一篇博客
  if(req.method === 'POST'&&  req.path ==='/api/blog/new') 
          const result = newBlog(req.body)
      return result.then(data =>
        return new SuccessModel(data,'添加成功')
    )
  
 ...省略

通过postman测试一下,

接下来完善并模拟所有的数据

controller

blog.js

const getList = (author,keyword) =>
  const promise = new Promise((resolve,reject)=>
    const data = [
      
        id:1,
        title:"标题A",
        content:"内容A",
        createTime前端进阶全栈入门级教程nodeJs博客开发(一)搭建环境与路由

前端进阶全栈入门级教程nodeJs博客开发(一)搭建环境与路由

前端进阶全栈入门级教程nodeJs博客开发(二)安装mysql完善api接口对接mysql

前端进阶全栈入门级教程nodeJs博客开发(二)安装mysql完善api接口对接mysql

前端进阶全栈入门级教程nodeJs博客开发(二)安装mysql完善api接口对接mysql

前端进阶全栈入门级教程nodeJs博客开发(二)安装mysql完善api接口对接mysql