从编程小白到全栈开发:基于框架开发服务端

上文中,我们了解了关于服务器端的一些概念知识,尤其是HTTP协议相关的最基本知识点,今天我想跟大家分享一下在平时正真的开发中,是如何来利用和体现这些内容的。

还记得我在《从编程小白到全栈开发:改造为全栈计算器》那篇文章中实现了一个Node.js的后端程序么?在该示例代码中,我们使用了Node.js基础库提供的HTTP API,开发了一个提供静态文件(caculator.html)和计算服务(/calc)的接口,不过说实话,这段代码虽然能工作,但还是比较简陋的,它在语义化、模块化、扩展性等方面都没怎么考虑过。

在实际软件项目或产品的开发中,除了让我们的程序满足特定功能方面的需求,其实还需要在开发的便利性、健壮性、可维护性、可扩展性、安全性等诸多方面进行思考和设计。

为了达到该目的,就需要对我们的代码进行一个良好的结构设计,对底层的API进行适当的封装,让他们使用起来更优雅好用。可喜的是,我们现在处在一个开源软件极度丰富的世界中,很多公司和优秀个人都将他们开发的各种软件产品、工具库、以及代码框架都开源出来供别人免费使用。基于Node.js的各类服务器端开源代码也是琳琅满目,光是用来开发Web服务的框架就有很多,其中比较知名的有如Express,Koa,Restify,Derby,Sails,Meteor,Egg.js等等。

我们这次就先挑一个比较成熟、业内使用较多的框架Express来学习一下基于框架的后端服务开发。

用Express重构计算器

我们就先把之前那个计算器的代码使用Express框架来重写一遍,看看重写完后和重写前的代码有什么区别。

步骤1:让我们找一个地方先新建一个文件夹,取名为express-calc

步骤2:通过命令行工具,进入到我们这个新建的express-calc目录下, 如:

cd express-calc

步骤3:通过npm创建配置来管理这个项目,执行以下命令:

npm init

过程中可以按提示修改相关配置项,如果现在还不太明白,可以直接一路按回车就行了。

执行完成后express-calc目录下会生成一个package.json文件。

步骤4:安装Express 执行以下命令,将Express安装进我们的项目:

npm install express --save

安装完成后,在express-calc目录下多出了一个node_modules目录,Express框架极其依赖的库都被安装到了该目录下。观察一下package.json文件,将发现其中也多出了一条Express相关的配置项,它代表安装的Express的版本信息。

步骤5:新建一个public目录,将之前的calculator.html放到该目录下

步骤6:新建一个server.js,编写如下代码:

const express = require('express')
const path = require('path')
const app = express()

// 启用静态文件中间件,将public文件夹设置为静态文件服务目录, 该目录下的文件可以通过URL直接访问
app.use(express.static(path.join(__dirname, 'public')))

// 数学计算服务
app.get('/calc', (req, resp) => {
    let num1 = parseFloat(req.query.num1);
    let num2 = parseFloat(req.query.num2);
    let operator = req.query.operator;

    var result = 0;

    if (operator === '+') {
        result = num1 + num2; // 相加
    } else if (operator === '-') {
        result = num1 - num2; // 相减
    } else if (operator === '*') {
        result = num1 * num2; // 相乘
    } else if (operator === '/') {
        result = num1 / num2; // 相除
    }

    resp.send('' + result);
})

app.listen(8888, () => {
    console.log('server is listening on port 8888 ...')
})

步骤7:启动服务。

我们可以通过直接执行node命令来运行我们的代码:

node server.js

也可以先在package.json的scripts配置中增加一行:

然后,就可以通过npm来启动服务了:

npm start

服务启动后,在浏览器中输入http://localhost:8888/calculator.html,就可以访问我们这个重写版的计算器啦。

点击下载该示例代码的完整源代码

对比分析

首先可以发现,在这次的开发中我们引入了npm的使用。npm它是一个JavaScript包管理工具,它具有从https://www.npmjs.com/网站的代码仓库中(或其他第三方代码仓库镜像,比如淘宝的镜像)下载开源代码库的功能,它也兼具项目中的库版本管理、库发布、命令行脚本管理执行等诸多功能,非常方便好用,我们完全可以围绕它来进行我们的Node.js服务端或前端项目的构建工作。

在我们的计算器项目中,我们通过npm将Express下载安装到我们的项目目录中,并自动在package.json中标记了Express的版本号,这样做的目的,是为了以后代码分享的方便。因为对于一个项目,其实我们自己编写的代码量并不会太多,但是通常会依赖很多第三方库,因此node_modules目录下面的文件会非常多非常大,你如果要把你的代码连同这些第三方库都一同给别人或上传到代码版本管理工具(如Git,SVN等)的时候,这将变得麻烦和糟糕。而使用npm这种包管理工具,只需要借助一个配置文件中的信息(package.json),我们在代码分享的时候,完全不需要把node_modules给别人,只需要把你自己的代码以及package.json给别人就行了,别人可以通过npm来根据package.json中记录的库和版本信息,下载所需要的库代码。你可以像这样在package.json所在的目录执行以下命令:

(你可以把你先前已有的node_modules目录删掉再试)

npm install

是不是很方便?!

接着,在代码层面,重构过后我们的server.js比原先的代码更简短干净了许多。最明显的地方,就是原先代码中需要对calculator.html文件的访问进行手动编码处理(匹配请求地址,用文件API读取本地文件,再向请求客户端输出文件),而使用了Express的代码中,由于可以使用Express框架提供的静态文件中间件,所以原先需要手动编码处理的静态文件访问功能,现在只需要一行代码就轻松搞定了:

app.use(express.static(path.join(__dirname, 'public')))

再者,原先对calculator.html文件的处理和/calc计算服务的处理都在同一个function中进行,使用if条件来判断具体要进入哪一个逻辑;而Express版本中,由于有了路由机制,所以每一个服务都可以根据各自的请求方式和URL规则独立编写:

app.get('/my/service1', (req, resp) => { 
    // req为Request对象
    // resp为Response对象 
    // ...
})

app.post('/my/service2', (req, resp) => { })

app.put('/my/service3', (req, resp) => { })

app.delete('/my/service4', (req, resp) => { })

这里的get, post, put, delete分别对应着我们前一篇文章《从编程小白到全栈开发:服务端的一些概念》中讲到的HTTP方法。Express框架提供的这种写法,可以让各个服务的定义更清晰,实现起来更独立、更有益于将功能模块化。

由于Express采用了中间件的设计理念,使得在每一个请求服务前插入各种额外的功能逻辑变得非常方便。比如,我们可以编写检查需要会话(Session)验证通过才能继续工作的中间件,或者用于过滤用户输入参数中非法内容以防止跨站脚本攻击(XSS)的中间件等。

我们可以尝试编写以下代码,放在/calc服务代码的前面:

// 这是一个简单的能打印出服务请求时间的中间件
app.use((req, resp, next) => {
    console.log(">>>> start time:", Date.now())
    next()  //调用下一个中间件
})

重新启动服务,然后访问你的计算器,你会发现每当你按下“计算”按钮的时候,命令行界面上就会输出一个时间戳信息来:

通过这个小小的示例,是不是对Express中间件的特性有点理解了?

另外提一点,在npm仓库中已经有非常丰富的开源Express中间件了,在开发时,先去npm仓库中找找是不是已经有现成的中间件可以使用,这会给你节约很多时间。

总结

Node.js的开源社区非常的活跃,npm仓库中也已经积累了大量的代码库,你可以通过阅读和使用别人的代码,来学习好的编码方式和设计思想,提高自身的开发能力。使用框架是你迈出的第一步!

合理利用已有资源,节约时间去创造更多价值。 欢迎关注一斤代码的系列课程《从编程小白到全栈开发》

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Web 开发

NodeJS那些事

下半年做了挺多活动型需求,因为我们业务人力有限,我在业务的策略是不依赖NodeJS。

20000
来自专栏java架构师

跨域请求数据解决方案整理

跨域请求数据解决方案主要有如下解决方法: JSONP方式 表单POST方式 服务器代理 Html5的XDomainRequest Flash request 分...

36570
来自专栏Python中文社区

Python爬虫抓取收集考试大纲

專 欄 ❈ Garfield_Liang,Python中文社区专栏作者。 博客地址:http://www.jianshu.com/u/cac1d39abfa9 ...

266100
来自专栏NetCore

不错的node.js入门

关于 本书致力于教会你如何用Node.js来开发应用,过程中会传授你所有所需的“高级”JavaScript知识。本书绝不是一本“Hello World”的教程。...

57180
来自专栏源码之家

WDCP 504 MySQL server has gone away 解决方法

16620
来自专栏小程序·云开发专栏

小程序的全栈开发新时代

小程序·云开发是微信团队和腾讯云团队共同研发的一套小程序基础能力,简言之就是:云能力将会成为小程序的基础能力。整套功能是基于腾讯云全新推出的云开发(Tencen...

12.9K180
来自专栏数据小魔方

R语言爬虫实战——知乎live课程数据爬取实战

本文是一篇R语言爬虫实战练习篇,同样使用httr包来完成,结合cookies登录、表单提交、json数据包来完成整个数据爬取过程,无需书写复杂的xpath、cs...

49560
来自专栏Golang语言社区

Golang学习--GroupCache的使用

groupcache 是 Brad Fitzpatrick 最新的作品,目标在于取代一部分memcached的功能。以官方的说明是:groupcache ...

73340
来自专栏Web项目聚集地

Javascript中的异步

9020
来自专栏zhisheng

0Day技术分析-1-基础知识

1 基础知识 本章介绍一些与0Day相关的基本概念及基础知识。 1.1. Bug与漏洞 有一个比较有趣的事件,话说某个软件中存在99个Bug,某一天研发人员心血...

34340

扫码关注云+社区

领取腾讯云代金券