利用node js快速模拟Web API

Web API即使通过网络进行调用的API接口,与具体的编程语言无关。现在常见的是通过标准的HTTP GET/POST请求,从服务器获取响应的资源或服务,服务器返回调用的结果内容,一般为xml格式或者json格式的数据(现在使用json的更多)。

在开发App的时候,一般原型设计好(如使用just in mind之类的工具)之后,我们会设计出与服务器交互的接口文档。一般情况下,App的开发进度(尤其原型)要快于服务器的开发进度。在App静态原型开发完到服务器实现所有的交互接口这段期间内,我们当然不能闲着。这时,我们可以本地模拟一个HTTP服务器,从而可以继续App的”动态化”开发。

由于对javascript比较熟悉,简单看了一下node js之后,就使用它来开发本地的HTTP服务器并提供各种交互的接口。这里记录一下是怎么一步一步实现的。

一步一步实现HTTP服务器

示例起见,杜撰了3个接口(无论多少个,原理都一样),如下:

焦点图
/sample_app/focus_pic

文章列表
/sample_app/article_list

文章详情
/sample_app/article_detail

我们可以将服务器划分为以下几个模块:

  1. 入口 - app.js,总体管理服务器。一般是启动服务器
  2. server模块 - server.js,负责服务器的配置与请求的转发。如服务器监听的端口,请求日志的记录,请求转发至具体的处理函数等
  3. router模块 - router.js,顾名思义,负责请求的路由功能。例如,我们在这里可以将不同的请求地址转发至不同的函数处理。
  4. request handlers模块 - request_handler.js,针对每个请求进行处理的函数都定义在这个模块里边。
  5. response template模块,由于我们只是快速模拟提供Web API服务的HTTP服务器,所以真正返回的内容写在模板里边即可。

其实3个接口的路由(将不同的请求转到对应的处理函数)按照道理应该在router模块中进行处理,但是因为针对每个接口的处理逻辑都是相同的,只是返回的内容不同,我就把路由逻辑转到request handlers模块中去了。具体如何写,可以根据实际的情况进行调整,这里边只是提供一个思路而已。

单看文字还是比较晦涩的,我们来看一下具体的代码:

server.js

/**
 * Created by FIMH on 2016/05/05.
 */
var http = require(‘http‘);
var url = require(‘url‘);

function start(route, handle) {
    function onRequest(request, response) {
        // 获取请求路径
        var parsedUrl = url.parse(request.url);
        var pathname = parsedUrl.pathname;

        console.log(‘Request for ‘ + pathname + ‘ received.‘);

        route(handle, parsedUrl, request, response);
    }

    http.createServer(onRequest).listen(9999);
    console.log(‘Server has started.‘);
}

exports.start = start;

可以看到,主要配置了HTTP服务器监听的端口 - 9999,以及打印了一条log信息,然后将请求转至router模块进行处理

router.js

/**
 * Created by FIMH on 2016/05/05.
 */
// 针对不同的请求,做出不同的相应
function route(handler, parsedUrl, request, response) {
    var pathname = parsedUrl.pathname;
    console.log(‘About to route a request for ‘ + pathname);

    // 禁止访问favicon.ico
    if (!pathname.indexOf(‘/favicon.ico‘)) {
        return;
    }

    // 这里不用检查请求路径是否正确,将路由放到handle对应的函数中去
    handler(parsedUrl, request, response);
}

exports.route = route;

这里我们主要拦截了对favicon.ico文件的访问,关于这个文件是什么,大家可以自行搜索。

前面也提到了,由于这个sample里边,每个接口的处理逻辑都是相同的,只是返回的内容不同,我就把路由逻辑转到request handlers模块中去了。

真正的处理逻辑都在下面这个模块中

requests_handlers.js

/**
 * 请求处理入口。
 */
function handleRequests(parsedUrl, request, response) {
    // 解码并解析querystring
    //var queryStringUtil = require(‘querystring‘);
    //var queryString = parsedUrl.query;
    //var queryStringResultObject = queryStringUtil.parse(queryString);

    var pathname = parsedUrl.pathname;

    // 在这里进行处理
}

exports.handleRequests = handleRequests;

这里,我只贴了一个请求处理的入口函数。

在这个地方我重构了一次,最初的处理逻辑大致如下:

    var templateName;
    var innerHtml;
    if (pathname == ‘/sample_app/focus_pic‘) {
       templateName = ‘focus_pic‘;
    } else if (pathname == ‘/sample_app/article_list‘) {
        templateName = ‘article_list‘;
    } else if (pathname == ‘/sample_app/article_detail‘) {
        templateName = ‘article_detail‘;
        innerHtml = ‘article‘;
    }

    if (templateName) {
        handleValidRequest(request, response, templateName, innerHtml);
    } else {
        handleErrorOutput(request, response, 400, ‘Invalid request url!‘);
    }

因为这里只是3个请求,看着还不明显,如果比较多了,那么if…else写起来就太烦了,这时候我想起来好多js语言的项目(如cocos 2d-js,egret)都会使用json文件作为项目的配置文件,依次来简化代码并提高灵活性。

这时,我们可以定义一个项目的配置文件,我这里取名叫appProperties.json,内容如下

{
  "route": {
    "/sample_app/focus_pic": {
      "template": "focus_pic"
    },
    "/sample_app/article_list": {
      "template": "article_list"
    },
    "/sample_app/article_detail": {
      "template": "article_detail",
      "inner_html": "article"
    }
  }
}

然后我们修改前面提到的模块 - requests_handlers.js

先定义一个全局变量var routeObj;

然后在函数handleRequests里这样处理:

// 解析route配置信息
    if (!routeObj) {
        var fs = require(‘fs‘);
        var propertiesPath = ‘./appProperties.json‘;
        var propertiesData = fs.readFileSync(propertiesPath, ‘utf-8‘);

        routeObj = JSON.parse(propertiesData);
    }

    var templateObj = routeObj[‘route‘][pathname];
    if (templateObj) {
        handleValidRequest(request, response, templateObj[‘template‘], templateObj[‘inner_html‘]);
    } else {
        handleErrorOutput(request, response, 400, ‘Invalid request url!‘);
    }

重构之后,无论接口有多少个,处理的代码依然是这几行;而重构前的方法,每添加一个接口,都需要增加一个 else if

拿算法复杂度的概念来比对,重构前就是O(n),而重构后则为O(1)。

关于response template模块的处理,这里就不贴代码了。主要是使用node js同步或者异步读取模板文件,还有对json对象的序列化,编辑与反序列化。大家有兴趣的话可以看整个sample的源代码,见文章底部。

总结与源代码

如果使用传统的方式,你需要安装一个http服务器 - 如apache,还有一个语言处理模块 - 如php。

而使用了node js之后,你只需要安装一个node运行时,剩下的http服务器,请求解析,处理,返回等全部使用js来进行编写即可,而且书写的代码量也很小。

整个项目的代码我放到github上了,详见nodejs_sample_app

时间: 2024-11-07 14:08:32

利用node js快速模拟Web API的相关文章

利用Node.js实现模拟Session验证的登陆

1.身份验证和用户登陆 在一般的Web应用上,如果要实现用户登陆,最常用,也是最简单的方法就是使用Session,基本的思路是在Session中保留一些用户身份信息,然后每次在Session中取,如果信息不正确或不存在,那么身份验证失败,正确则成功. Session和Cookie是两个很相似的东西,都是字符串,只不过Session是保存在服务器上的,而Cookie是保存在本地的,所以Cookie是不能用作身份验证的.Session故名思议,肯定和客户端与服务器间建立的会话相关,Session的工

利用node.js搭建简单web服务器的方法教程

前言 使用Nodejs搭建Web服务器是学习Node.js比较全面的入门教程,因为要完成一个简单的Web服务器,你需要学习Nodejs中几个比较重要的模块,比如:http协议模块.文件系统.url解析模块.路径解析模块.以及301重定向问题,下面我们就简单讲一下如何来搭建一个简单的Web服务器. 早先不使用web服务器的情况下想要在浏览器端访问本地资源,可以利用firefox浏览器,其可以自己启动一个小型web服务器. 为了让刚接触node的人也能大体看懂,本文的代码我将尽量简化. 准备 首先,

笔记-Node.js中的核心API之HTTP

最近正在学习Node,在图书馆借了基本关于Node的书,同时在网上查阅资料,颇有收获,但是整体感觉对Node的理解还是停留在一个很模棱两可的状态.比如Node中的模块,平时练习就接触到那么几个,其他的一些模块暂时只会在学习的时候接触到,不常用便就荒废了.正所谓好记心不如烂笔头,多做笔记还是更有利于理解和记忆.自己做的总结也方便回头复习,所以决定踏上漫长的修炼之旅-- Node提供了许多API,其中一些比较重要.这些核心的API是所有Node应用的支柱,你会不停的用到他们. HTTP服务器 Nod

Node.js+MongoDB+AngularJS Web开发

这篇是计算机类的优质预售推荐>>>><Node.js+MongoDB+AngularJS Web开发> MEAN全栈工程师首部实战书 从服务器到浏览器基于JavaScript的Web应用程序权威指南 内容完整细致可直接用来入门任一技术 编辑推荐 Node.js是一种领先的服务器端编程环境,MongoDB是最流行的NoSQL数据库,而AngularJS正迅速成为基于MVC的前端开发的领先框架.它们结合在一起使得Web程序员能够完全用JavaScript创建从服务器到客户端

纯干货 | Node.js快速入门指南与实践

前言 Node.js知识点虽然不多,但是想要通篇的看完并快速上手还是需要一些时间的.而这篇文章主要总结工作中Node.js一些常用模块API的用法以及优秀的第三方模块,帮助你快速的上手.Good Luck?????? 惯例 Node.js是基于Chrome V8引擎的Javascript运行环境. console - 控制台 1.控制台打印信息 console.log('日志信息'); console.warn('警告信息'); console.debug('调试信息'); console.er

利用Node.js对某智能家居服务器重构

原文摘自我的前端博客,欢迎大家来访问 http://www.hacke2.cn 之前负责过一个智能家居项目的开发,外包重庆一家公司的,我们主要开发服务器监控和集群版管理. 移动端和机顶盒的远程通信是用中间服务器完成交互,服务器使用MINA NIO框架,非阻塞式的,可以看看以前博客了解下某智能家居项目框架学习总结,或者其他资料JAVA NIO原理,基于MINA框架快速开发网络应用程序. 在移动端或者机顶盒登录后会使用spring security 进行加密,主要是结合用户名和密码来加密,生成一个唯

《Node.js+MongoDB+AngularJS Web开发》读书笔记及联想

总体介绍 <Node.js+MongoDB+AngularJS Web开发>,于2015年6月出版,是一本翻译过来的书,原书名为<Node.js,MongoDB and AngularJS Web Development>,总的来说是一本讲述如何用Javascript进行B/S架构全栈开发的书. 该书主要讲解4种技术(框架),分为6个部分29个章节.4种技术即Node.js.MongoDB.Express.AngularJS,业内称为MEAN:6个部分我个人理解为: 基础(引言).

如何更好的利用Node.js的性能极限

通过使用非阻塞.事件驱动的I/O操作,Node.js为构建和运行大规模网络应用及服务提供了很好的平台,也受到了广泛的欢迎.其主要特性表现为能够处理庞大的并且高吞吐量的并发连接,从而构建高性能.高扩展性的互联网应用.然而,Node.js单线程的的工作方式及有限的可管理内存使得其计算性能十分有限,限制了某些场景中的应用.近日,Jut开发团队的工程师Dave Galbraith分享了他们所遇到的Node.js的限制以及超越这些限制的方法.接下来,本文就详细分析其所遇到的问题及解决思路. 首先,Jut团

node.js 快速体验

对于一个从事js的工作人员,怎么能不知道node.js呢! 一.安装node.js 在window上安装,http://nodejs.org上的windows installer 下载安装,在安装过程中本人喜欢点击next 到安装完成... 如果你不确定你已经成功安装 打开cmd 输入 node -v 出现 版本信息  表示你已经成功安装. (已经默认安装了 npm....) 二.可爱的helloworld 1.打开编辑器  新建一个index.js (随便的名称) 写下:console.log