手把手教你零基础之Node.js搭建API服务器
今天小编就为大家分享一篇关于零基础之Node.js搭建API服务器的详解,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下。如有不足之处,欢迎批评指正。
零基础之Node.js搭建API服务器
这篇文章写给那些Node.js零基础,但希望自己动手实现服务器API的前端开发者,尝试帮大家打开一扇门。
HTTP服务器实现原理
HTTP服务器之所以能提供前端使用的API,其实现原理是服务器保持监听计算机的某个端口(通常是80),等待客户端请求,当请求到达并经过一系列处理后,服务器发送响应数据给到前端。 平时大家通过Ajax调用API,即是发起一次请求,经过服务器处理后,得到结果,然后再进行前端处理。如今使用高级编程语言,要实现服务器那部分功能已经变得非常简单,接下来我们了解一下使用Node.js如何实现。
什么是Node.js?它可以做什么?
Node.js是一个JavaScript的运行时(runtime),它提供了大量用JS与操作系统打交道的API,通过这些API,我们可以调用本地程序、读写磁盘、监听端口、发起网络请求等,这足以开发出一个功能完善的Server。
前期准备
简单介绍完Node.js,开始写代码之前,我们需要安装Node.js,安装详细过程就不说明了,请大家Google或者百度。不同系统安装过程不一样,如果是Linux、Mac,会相对顺利且遇到问题的可能性较低。 判断安装成功与否,windows下,在cmd中执行node -v,Linux、Mac下,在shell中执行node -v,正常输出版本号说明安装成功。
tips: windows如果提示命令未找到,可能是未配置环境变量
实现简单的Server
Node.js安装成功,我们找个地方新建目录my-server作为我们的存放代码的地方,接下来所有的代码都在该目录下。首先,在my-server的目录下新建文件index.js,用如下代码实现一个简单的Server:
// index.js // 通过require获取两个node内置模块 const http = require('http'); const nUrl = require('url'); // '127.0.0.1'表明只有本机可访问,'0.0.0.0'表示所有人可访问 const hostname = '127.0.0.1'; const port = 3000; // 通过http.createServer获取一个server实例 // 其中(req, res) => {},在服务器每次接收到请求时都会被执行 const server = http.createServer((req, res) => { let method = req.method; // 客户端请求方法 let url = nUrl.parse(req.url); // 将请求url字符串转换为node的url对象 // 如果客户端GET请求'/',会执行这个分支里面的逻辑 if (method === 'GET' && url.pathname === '/') { res.statusCode = 200; res.setHeader('Content-Type', 'text/plain'); res.end('Hello World'); return; } // 如果客户端GET请求'/api/user',会执行这个分支里面的逻辑 if (method === 'GET' && url.pathname === '/api/user') { res.statusCode = 200; res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify({ code: 0, msg: '', result: { username: 'shasharoman' } })); return; } // 没有匹配其他分支的话,执行以下逻辑 res.statusCode = 404; res.setHeader('Content-Type', 'text/plain'); res.end('Not Found'); }); //在此我向大家推荐一个前端全栈开发交流圈:619586920 突破技术瓶颈,提升思维能力 // server开始监听,等待请求到来 server.listen(port, hostname, () => { console.log(`Server running at <a href="http://${hostname}:${port}/`);"
文件内容编辑保存后,在my-server目录下通过命令node index.js启动服务,然后在浏览器中访问http://127.0.0.1:300/、http://127.0.0.1:300/api/user、http://127.0.0.1:300/xxx观察不同结果。
这是官方Guides经过小小修改得到的代码,添加部分注释以及额外逻辑。主要为了更清晰传达以下几个知识点:
- 从req对象上获取method与url,这个req对象是客户端请求的“抽象表现”,平时写Ajax指定的绝大部分内容都可以从该对象上获取
- 中间添加的两个if分支,主要是为了让大家了解服务器如何区分不同请求,决定做不同事情,即路由概念
- Content-Type: application/json,通常API会使用的响应格式,表明返回数据是json格式,这是一个HTTP头部,属于HTTP协议相关知识
- statusCode:404,HTTP最常见的错误“Not Found”,也属于HTTP协议相关知识
往前优化一步
通过上面的代码,实现了一个简单Server,但真实场景下我们会这样去实现吗?答案是肯定不会,所以我们还需要一步步完善,做以下几个修改:
- 增加config,在其中配置hostname,port
- 增加controller,用于分层以及分模块
- 增加route,用于定义路由
代码不多,一共五个文件:
- config.js,配置文件
- route.js,路由定义文件
- controller/account.js,账号模块业务实现文件
- controller/index.js,业务汇总并暴露给外部
- index.js,项目启动文件
// config.js exports = module.exports = { hostname: '127.0.0.1', port: '3000' };
// route.js exports = module.exports = [{ method: 'GET', path: '/api/user', impl: 'account.userById' }, { method: 'POST', path: '/api/user', impl: 'account.createUser' }]; //在此我向大家推荐一个前端全栈开发交流圈:619586920 突破技术瓶颈,提升思维能力
// route.js exports = module.exports = [{ method: 'GET', path: '/api/user', impl: 'account.userById' }, { method: 'POST', path: '/api/user', impl: 'account.createUser' }];
// controller/index.js exports.account = require('./account');
// index.js const http = require('http'); const nUrl = require('url'); const config = require('./config'); const controller = require('./controller'); const route = require('./route').map(item => { console.log(`route ${item.method}:${item.path}`); let tuple = item.impl.split('.'); item.impl = controller[tuple[0]][tuple[1]]; return item; }); const server = http.createServer((req, res) => { let method = req.method; let url = nUrl.parse(req.url); let matchRoute = route.find(item => { return item.method === method && item.path === url.pathname; }); if (matchRoute) { matchRoute.impl(req, res); return; } res.statusCode = 404; res.setHeader('Content-Type', 'text/plain'); res.end('Not Found'); }); server.listen(config.port, config.hostname, () => { console.log(`Server running at <a href="http://${config.hostname}:${config.port}/`);" rel="external nofollow">http://${config.hostname}:${config.port}/`); </a>}); //在此我向大家推荐一个前端全栈开发交流圈:619586920 突破技术瓶颈,提升思维能力
依旧是用node index.js启动Server,如果要在现有模式下开发一个API,主要就两步: 在route.js中定义路由
在controller/中实现
做这个程度的优化,只是为了向大家传达一些比较宽泛的概念,还不是真正用来写API服务,只是为了大伙练练手。 这个程度还达不到真实场景需求,还需要经过几轮改造,包括模块、层、common、lib、query解析,body解析、更灵活的route等一系列事情,限于篇幅,有机会在一一讲述。 经过我的描述以及代码示例,如果大家有兴趣学习Node.js,建议多搜搜相关知识,保持关注,然后在逐步去熟悉Node.js流行的Web框架如:Express、Koa等,不过框架只是更高层面的封装,基础的概念以及知识还是需要花时间才能掌握。 如果前端想尝试后端编程,请一定先学习HTTP协议,推荐《HTTP权威指南》从头到尾认真看一遍。
结语
感谢您的观看,如有不足之处,欢迎批评指正。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
全网Star最多的Spring Boot开源教程 2019 年要继续更新了!
从2016年1月开始写博客,默默地更新《Spring Boot系列教程》,从无人问津到千万访问,作为一个独立站点http://blog.didispace.com ,相信只有那些跟我一样,坚持维护自己独立博客的童鞋才能体会这有多么不容易。 由于没有CSDN、博客园这样的权重优势,各种发布于这些平台上的洗稿文章与相似内容,就算发布时间较晚,它依然可以在百度上占据很大的搜索优势,以至于一些读者在读了其他人发布于CSDN、博客园上的一些文章之后看到我的原文,再来我这里喷我抄袭,这样的现象早已经习以为常了。但是庆幸,这些内容的很大一部分读者都是科学上网的好手,我大部分的流量来源都源自谷歌,这点不得不佩服谷歌对原创与一手内容的尊重,这才让我们这些能够独立思考与写作分享的技术人可以一直坚持下去。 不知道从什么时候开始,技术圈里的浮夸运营风也越来越重,各种原本非常有含金量的数据也变得越来越虚假,洗稿、盗版等内容的横行,不断侵害着所有原创作者的切身利益。也许这其中包含各种原因:运营KPI的压力,一些大v自媒体的粗暴价值观宣导,所谓的运营套路分享等等。很多原本坚持原创和自有版权的技术人,也都逐步顶不住诱...
- 下一篇
MySQL 数据库设计经验总结
背景 此文仅在数据库设计层面进行探讨,数据库的运维与底层调优不在讨论范围之内。 更丰富的知识可以在 MySQL 官网文档 查阅。 学习官方文档也是一种好的习惯,能更系统更全面的掌握某一领域的知识,具体知识点也可以通过搜索引擎快速获取,但是很难让你深入到细节或者上升到宏观层面。 基础知识 存储引擎 通常来说,我们做业务开发,指定存储引擎为 InnoDB 即可。 字符集 通常来说,只要指定为 utf8 即可。 如果业务中需要使用 emoji 表情,那么就必须要设置为 utf8mb4 MySQL 可以在 server 级、database 级、table 级、column 级进行字符集的设置。 数据库设计 总则 命名以“_”分割 数据库层面还是推荐使用“_”作为分割,这里多说几点: 1、约定俗成。长久以来不仅 MySQL ,其他数据库也推荐使用“_”,这是一种 SQL 规范。 2、JSON 返回的数据一般也会将驼峰转化为“_”来分割。 3、JAVA POJO 对象还是使用驼峰命名,现在的 JSON 转换工具, ORM 工具可以很便捷的指定参数来设置驼峰或者下划线的偏好。 如果仅是使用 Myb...
相关文章
文章评论
共有0条评论来说两句吧...