【koa + vue + es6 + node】全家桶前后端分离项目实战(2)?

268 阅读7分钟

接着前面的文章,我们慢慢得把菜鸟前端写接口这件事向前推进。今天主要介绍koa的使用,这是完成后端接口中非常关键的一步。 OK,准备好小板凳,我要开始讲故事了。

什么是koa?

先看下官方的解释:基于Node.js平台的下一代web开放框架。这一句话的关键字是web框架,那啥是web框架呢?类似的框架有express,可以跟她类比一下(不好意思,代码敲久了,看谁都像那个她了)。如果有不熟悉express的朋友,我在这样类比一下:我想在一个水池里养一些小动物,比如我可以在这个池子里养一些小鱼,那么一年后我就能打捞一些小鱼出来;或者我们可以在这个池子里养一些青蛙,那一年后我们也可以获得一批成年青蛙;或者我们可以养一些黄鳝,那么一年后我们能得到一些成年黄鳝......

我们都知道进行前后端交互需要进行http请求,它存在request=> 处理数据 => response这第三个过程对吧。我们再来类比一下:我们将小鱼苗投向水池就像http请求中的request部分,小鱼在水池生存过程就像处理数据的过程,而打捞鱼儿就类似response的部分。而koa作为一个web框架,就相当把投放和捕捞这两部分都帮我们完成了,我们只需要专注于水池生存的这一个部分。换句话说:koa处理了request和response,我们需要做的就是编写中间数据处理的过程,这部分叫做中间件。

中间件这个词也挺形象,这个跟我们生活中的中间商很类似。我老家是在中国很南的地方,有花炮之乡的美名,所以我的家乡是属于花炮的生产商。但是在我们临市经常会有这样一批人,他们购买我们的花炮,然后在转手卖给其他有需要的人,这就是中间商。他们控制这生产商(request)的产品来源,同时也有大量的终端客户(response),而他们做的是中间连接的一个过程,或者能高价卖出,先爽一把;或者薄利多销,扩大市场影响(这些都是中间过程会发生的事)。那我们现在依赖koa做的就是这个中间商的事。

听完了我家乡中间商的故事,我们回到现实生活中,看看我们有了货源的保障(request)和终端客户(response),我们作为程序中的中间商能做点什么呢?好的,我先拿个小生意跟大家分享一下。

简单的例子

// app.js
const Koa = require('koa')
const app = new Koa()

// 中间过程处理数据,输出结果
app.use((ctx, next) => {
    const str = 'hello world'
    ctx.body = str
})
// 绑定端口3000
app.listen(3000)

接下来我们需要执行命令node app就将一个web服务器搭建好了,然后在浏览器上输入localhost:3000就能在页面上看到hello world的文字。前面的const Koa = require('koa');const app = new Koa()和后面的app.listen(3000)都是搭建web服务器建立连接必须要的,是固定的写法。这两个步骤可以看成是request接口成功。然后ctx.body = str属于输出response的过程,app.use((ctx, next) => {const str = 'hello world';})就属于中间件的处理过程。这个中间环节也很简单,就是定义了一个变量str,然后就是没了,只做了这样一件事。然后response把中间环节做得事的结果输出,我们就看到了在本地,端口是3000的服务器中看到了hello world

而koa又设计的非常简单,如上面的这个例子所示,几行代码就完成了服务器建立并返回的事。如果我们要做更复杂一点的事情,就需要依赖于其他的中间件来完成。这个跟vue也有点类似:你看,vue只是提供了MVVM的模型,你如果还要做页面路由就要跟VueRouter说一句:“姐姐,帮帮我把页面路由搞定吧(没办法,代码敲多了看谁都像姐姐)”,如果要做全局的数据管理还要跟Vuex说一句:“哥哥,帮我做一下数据管理吧”。

而koa似乎也很懂这一套。

当他要获取服务器静态资源的时候,他就会跟KoaStaticCache打声招呼:小姐姐,帮我读取一下静态文件,等会有好吃的给你;当他要读取接口时,会跟KoaRouter说一句:小哥哥,帮我读取一下路由啊,等会帮你上分;当他要读取post请求数据时,会跟KoaBodyparser说一句:阿姨,那个请求是post,麻烦你帮我拿一下他的请求数据吧。所以大多数时候,在使用koa的同时,下面这些插件也常常会出现:

  • koa-static-cache:静态文件代理服务
  • koa-router:路由
  • koa-swig:模板引擎
  • koa-bodyparser:post请求的body参数解析

有了前面的这些基础,可以进入项目了。

在这个项目中涉及到上面知识点的就只有server/app.jsserver/routes/main.js这两个文件。是不是超级简单,就问你是不是?

好那我们来解析这两个文件做了什么?

解读项目文件

app.js

// 这部分是将上面提到的几个插件引入
const Koa = require('koa')
const KoaStaticCache = require('koa-static-cache')
const bodyParser = require('koa-body-parser')
const router = require('./routes/main')

const app = new Koa()


// 读取服务器中的静态文件,例如css,图片等内容
app.use(KoaStaticCache(__dirname + '/static', {
    prefix: '/static',
    maxAge: false,
    gzip: true
})
)
// 对post请求的解析
app.use(bodyParser({}))

// 将路由挂载到app上
app.use(router.routes())

app.listen(3000)

第一个要说的是app.use(KoaStaticCache(...))这个方法。这是读取服务器中静态文件的方法。静态文件指的是比如css、图片等资源。这里的配置指的是静态文件在当前文件夹下的static,不使用缓存,使用gzip压缩。但是我这个gua64项目里没有引入静态文件(目的是为了教大家怎么用这个)。

第二个要说的是app.use(bodyParser({})),app.use的意思是使用该中间件。执行该语句之后,就能在ctx.request.body中找到对应的入参了。同样我在这个demo中没有用到post请求,写出来是为了演示这个东西怎么用。

第三个要说的是app.use(router.routes()),我把所有的路由都放在了server/routes/main.js文件中,这里的路由其实就是我们常说的接口。接口不就是一个有映射关系的地址嘛。具体的接口信息我们看main.js,前面的这些都是固定写法 + 配置,看看官方文档很快就能动手操刀了。

main.js

// 查询内容接口
router.get('/findContent', async ctx => {
    const searchName = ctx.query.searchName || ''
    // 查找包含某个字段的数据
    let {count, rows} = await Models.Contents.findAndCountAll({
        where: {
            [Op.or]: [
                {
                    name: {
                        [Op.like]: `%${searchName}%`
                    }
                },{
                    desc: {
                        [Op.like]: `%${searchName}%`
                    }
                }
            ]
        },
    })
    ctx.body = {
        code: 0,
        count: count,
        data: rows.map(item => {
            return {
                id: item.id,
                contentId: item.contentId,
                name: item.name,
                contentList: item.contentList,
                desc: item.desc,
                likeCount: item.likeCount
            }
        })
    }
})

看一下上面的查询内容接口。是不是跟我前面写的简单的例子一毛一样?这里的中间环节就是去数据库中找到对应条件的内容,也就是这里的变量countrows,拿到了之后按照前端要的数据格式返回出去,然后就没了。简单到爆炸。

至于怎么查询数据库中的内容我们放在下节课来讲,这不是这节课的重点。

总结

我们开始先了解了koa是什么东西,然后用水池的例子跟大家类比了一下koa做了什么,我们依赖于koa能做什么,并且相互协作让整个服务跑起来。然后我用一个很简单的例子演示了一下怎么使用koa这个东西。最后我把项目中用到koa的部分单独拎出来分析,发现他在项目中的使用和我那个例子也是惊人的相识。所以,我个人认为koa最关键的点是在app.use()函数中对于数据处理的这部分内容,拿到了这部分内容返回给前端,就完了。

下一篇我们将对sequelize和sequelize-cli的使用做一个分析。

另外我自己新建了一个QQ群,群号码是:1103713567(全栈开发跳板群)。方便大家一起交流前端方面或者项目方面的问题。