Node.js实现RESTful api,express or koa?
文章导读:
一、what's RESTful API
1.1 RESTful架构
要理解什么是RESTful API我们可以先看一下什么是RESTful架构。
REST是Representational State Transfer的缩写,我们可以理解为它的含义是“表现层状态转化”,wikipedia是这样说的:“an architectural style that abstracts the architectural elements within a distributed hypermedia system”,这就是REST互联网软件的架构原则。
我们可以说如果一个架构符合REST原则,就称它为RESTful架构。
1.2 RESTful API
那么回到我们的RESTful api,我们为了有一种统一的机制,方便不同的前端设备与后端进行通信于是便有了 RESTful API这一套目前比较成熟的互联网应用程序的API设计理论。那么我们为了设计一个合理,好用的api,需要做些什么呢?简单的说大致需要做到以下几点:
1. api与用户的通信协议总是使用HTTPs
2. 我们尽量将API部署在专用域名下:https://api.example.com
3. url中有标示api版本号的字段:https://api.example.com/v1/
4. 路径带有明确的含义:https://api.example.com/v1/animals
5. 明确资源的具体操作类型,使用相应的HTTP方法:GET/POST/PUT/DELETE/PATCH
6. api中提供过滤信息的参数:?page=2&per_page=100:指定第几页,以及每页的记录数
7. 请求api后服务器需要返回明确的状态码,如果出错,带有错误处理
其实我们可以简单的理解为RESTful API就是更加规范的API。
下面我们就可以开始基于Nodejs的express和koa来实现一些例子理解下RESTful API。
二、Express RESTful API
2.1简单的get数据库中的数据
我们先通过一个简单些的只get获取数据库中数据的例子开始:
2.1.1 准备工作:
确认我们已经安装了nodejs express;
install mongodb数据库mac;
2.1.2 先开始最简单的例子:
目录结构,data是数据库相关的目录,我们可以先忽略掉:

确保我们的package.json文件中有mongodb等依赖:
{
"name":"node-api",
"main":"server.js",
"dependencies":{
"express":"~4.0.0",
"mongoose":"~3.6.13",
"body-parser":"~1.0.1",
"morgan":"~1.5.3",
"mongodb":"~2.0.33",
"monk":"~1.0.1"
}
}
在server.js中定义简单的路由和进行数据库操作:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var path = require('path');
//database
var mongo = require('mongodb');
var monk = require('monk');
var db = monk('localhost:27017/restdata');
//app.use()里面没有函数
app.use(bodyParser.urlencoded({ extended : true}));
app.use(bodyParser.json());
app.use(express.static(__dirname+'/public'));
var collectorder = db.get('orderlist');
var collectuser = db.get('userlist');
app.get('/orders',function(req,res){
collectorder.find({},{limit:20},function(err,orders){
res.json(orders);
});
});
app.get('/users',function(req,res){
collectuser.find({},{},function(err,users){
res.json(users);
});
});
app.get('/users/:name',function(req,res){
//var collection = db.get(req.params.name);
//console.log(req.params.name);
collectuser.find({name:req.params.name},{},function(err,docs){
res.json(docs);
});
});
//客户端通过请求adduser接口post数据进入数据库
// app.post('/adduser',function(req,res){
// var db = req.db;
// collectuser.insert(req.body,function(err,result){
// res.send(
// (err == null) ? {msg:''}:{msg:err}
// );
// });
// });
app.listen(3000);
数据库操作:
mongod --dbpath c:\node\nodetest2\data (项目中data目标路径)
新开一个控制台窗口运行:
mongo
use nodetest2(意义上的数据库名称)
db.userlist.insert({'username' : 'test1','email' : 'test1@test.com','fullname' : 'Bob Smith','age' : 27,'location' : 'San Francisco','gender' : 'Male'})
我们可以查看[monk] 的api,查看数据库的操作方法
如果没有什么问题的话,两个控制台窗口应该是这样的:

运行实例:
node server.js
访问url就可以看到我们获取到了的数据:

[查看项目源码]
2.2 使用express实现数据交互(get/post/delete)
实际上,我们刚才的例子并不算是一个完整的express的项目。我们只是用到了其中的几个API。我们通过express-generator生成的express项目的脚手架应该是这个样子的:

我们可以看到入口的app.js文件,以及控制路由的routes和控制显示的views文件夹,里面存放了jade模板的文件。很好地组织了项目的目录。
可以从express官方github开始,快速上手express:[expressjs].
这里说的数据交互的例子,有个非常详细易懂的教程:[CREATING A SIMPLE RESTFUL WEB APP WITH NODE.JS, EXPRESS, AND MONGODB]
然而也可以直接获取我仓库中的项目源代码:[RESTful API datachange]
三、KOA RESTful API
3.1 简单get数据
同样,koa版本我们也从最简单的实例开始。
1.目录结构,同样,我们也先忽略跟数据库相关的data文件夹:

2.确保我们的package.json文件中依赖了koa koa-route mongoose 和monk等:
{
"name": "koarestapi",
"version": "0.0.1",
"description": "",
"main": "app.js",
"dependencies": {
"co-body": "~0.0.1",
"co-monk": "~0.0.1",
"koa": "~0.1.2",
"koa-route": "~1.0.2",
"koa-router": "~2.2.0",
"kongo": "~0.0.3",
"mongoose": "~3.8.3",
"monk": "~0.7.1"
},
"author": "yixuan"
}
3.同样在app.js中定义koa版本的路由和简单的数据库操作:
var koa = require('koa');
var route = require('koa-route');
var app = module.exports = koa();
var monk = require('monk');
var wrap = require('co-monk');
var db = monk('localhost:27017/apitest');
var books = wrap(db.get('books'));
app.use(route.get('/book',list));
app.use(route.get('/book/:title',show));
function *list(){
var res = yield books.find({});
this.body = res;
}
function *show(){
title = decodeURI(title);
var res = yield books.find({title:title});
this.body = res;
}
if(!module.parent) app.listen(3000);
我们看到了generator的影子。
4.在上面的express版本中我们使用了自己的数据库中的数据,那么在实际的开发过程中,可能我们会想要调试本地已有的json文件中定义的数据。于是我们同样先起来mongo:
mongod --dbpath ~/work/Node-KOA/koarestapi/data(我们项目目标路径)
然后把数据指向项目中的json文件:
mongoimport --db apitest --collection books --file data.json
注意这对json文件中的数据格式稍有要求:[mongodb可能报错]
5.运行实例:
node --harmony app.js
然后就可以看到我们定义在data.json中的数据了 :

3.2 更进一步的koa版本的restapi
同样的,上面只是个简单的例子。使用koa generator-k生成的项目脚手架应该是这样的:

我们在入口文件app.js中定义基本的依赖和访问入口处理,在controller文件夹中的index.js中定义路由操作,在view中定义页面显示相关。
非常典型的MVC目录结构。
更加完整的koa版本的REST项目可以在这里看到:[KOA-REST]
四、express还是koa?
我们实际动手写过express的项目和koa的项目的话,就会有所体会,相比于koa,express做的事情要多一些,因此他的体积也相对比较大。
在上面两个例子中我们可以看到,在express版本的例子中我们使用它内置的路由就解决了问题,但是在KOA中我们需要额外的路由中间件,其实更准确的说,koa 内核中没有捆绑任何中间件,连常用的 post body 解析都没有...但这正体现出了koa的优势,koa的体积非常小,表现力更强,它使得中间件的编写变得更加容易。其实可以说,Koa基本上就是一个只有骨架的框架,它具有极强的拓展性,我们可以自己书写可充用和更加符合实际业务场景的中间件,而不用妥协的使用Express自带的中间件。Koa虽然小,但是它通过生成器(generators JavaScript 1.7新引入的,用于解决回调嵌套的方案)减少了异步回调,提高代码的可读性和可维护性,同时改进了错误处理(Express的错误处理方式相当糟糕)。
同时,Koa是一个采用面向未来的ES6的框架,比如说随处可见的generator函数。
虽然Koa还不是那么的稳定,但是毫无疑问的它是面向未来的,下一代Nodejs框架。
那么Koa相比于Express到底优势体现在那些方面呢?总的来说,koa 的先天优势在于 generator,带来的主要好处如下:
更加优雅、简单、安全的中间件机制
更加简单、优雅地异常处理
更加优雅地异步编程方式
这里有更加官方的说明:[Koa vs Express]
其实,koa 与 express 是共享底层库的,如果你会使用 express ,那么只要理解 generator 与 koa 框架 api,就可以快速上手。
如果还没有使用过express那么不如直接开始学习Koa,从这里开始:[koa 中文网]
五、参考资料
[install mongodb]
[express Routing]
[simple restful api]
[restful web app node express mongodb]
[koa examples]
[monk api]
[理解RESTful架构]
[RESTful api设计指南]
[koa 中文文档]
[introduction to generator&koajs part1]
[introduction to generator&koajs part2]
&ps-接下来文章预告:
yield语句与Generator函数
KOA实践
Node.js实现RESTful api,express or koa?的更多相关文章
- Node.js:RESTful API
ylbtech-Node.js:RESTful API 1.返回顶部 1. Node.js RESTful API 什么是 REST? REST即表述性状态传递(英文:Representational ...
- Node.js 框架对比之 Express VS Koa
背景 上图是一个典型的采用 Node.js 开发 web 应用的前后端结构,下面介绍一下 Node 服务层在其中的作用以及使用 Node.js 的一些优劣. Node 服务层作用: 请求代理 传统做法 ...
- Node.js学习 - RESTFul API
REST Representational State Transfer (表述性状态转移), 是一组架构约束条件和原则.满足这些约束条件和原则的应用程序或设计就是RESTful. RESTful W ...
- node.js Web应用框架Express入门指南
node.js Web应用框架Express入门指南 作者: 字体:[增加 减小] 类型:转载 时间:2014-05-28 我要评论 这篇文章主要介绍了node.js Web应用框架Express入门 ...
- mac下配置Node.js开发环境、express安装、创建项目
mac下配置Node.js开发环境.express安装.创建项目 一.node.js的安装 去官网下载对应的平台版本就可以了,https://nodejs.org 二.express安装 sudo n ...
- Koa -- 基于 Node.js 平台的下一代 web 开发框架 koa.bootcss.com
Koa -- 基于 Node.js 平台的下一代 web 开发框架 koa.bootcss.com
- [转]Node.js框架对比:Express/Koa/Hapi
本文转自:https://www.cnblogs.com/souvenir/p/6039990.html 本文翻译自: https://www.airpair.com/node.js/posts/no ...
- [译]Node.js框架对比:Express/Koa/Hapi
本文翻译自: https://www.airpair.com/node.js/posts/nodejs-framework-comparison-express-koa-hapi 1.介绍 直至今日, ...
- Node.js的高性能封装 Express.js
Express 是一个简洁而灵活的 node.js Web应用框架, 提供一系列强大特性帮助你创建各种Web应用.Express 不对 node.js 已有的特性进行二次抽象,我们只是在它之上扩展了W ...
随机推荐
- ABP教程-打造一个《电话簿项目》-目录-MPA版本-基于ABP1.13版本
此系列文章会进行不定期的更新,应该会有6章左右. 感兴趣的朋友可以跟着看看,本教程适合已经看过ABP的文档但是又无从下手的小伙伴们. 初衷: 发布系列教程的原因是发现ABP在园子火了很久,但是发现还是 ...
- JavaScript String对象
本编主要介绍String 字符串对象. 目录 1. 介绍:阐述 String 对象的说明以及定义方式. 2. 实例属性:介绍 String 对象的实例属性: length. 3. 实例方法:介绍 St ...
- CodeSimth - .Net Framework Data Provider 可能没有安装。解决方法
今天想使用CodeSimth生成一个sqlite数据库的模板.当添加添加数据库的时候发现: .Net Framework Data Provider 可能没有安装. 下面找到官方的文档说明: SQLi ...
- .NET CoreCLR开发人员指南(上)
1.为什么每一个CLR开发人员都需要读这篇文章 和所有的其他的大型代码库相比,CLR代码库有很多而且比较成熟的代码调试工具去检测BUG.对于程序员来说,理解这些规则和习惯写法非常的重要. 这篇文章让所 ...
- vue.js初探
前言 入手2016最火前端框架之一vue.js.大概从网上找了些资料看了下vue.js,从网上的资料来看只能惊叹其发展速度太快,让我意外的是其作者是华人的前提下作品这么受欢迎. 网上的博客和教程各种组 ...
- C# BackgroundWorker 详解
在C#程序中,经常会有一些耗时较长的CPU密集型运算,如果直接在 UI 线程执行这样的运算就会出现UI不响应的问题.解决这类问题的主要途径是使用多线程,启动一个后台线程,把运算操作放在这个后台线程中完 ...
- 微信小程序体验(1):携程酒店机票火车票
在 12 月 28 日微信公开课上,张小龙对微信小程序的形态进行了阐释,小程序有四个特定:无需安装.触手可及.用完即走.无需卸载. 由于携程这种订酒店.火车票和机票等工具性质非常强的服务,非常符合张小 ...
- Android 旋转屏幕--处理Activity与AsyncTask的最佳解决方案
一.概述 运行时变更就是设备在运行时发生变化(例如屏幕旋转.键盘可用性及语言).发生这些变化,Android会重启Activity,这时就需要保存activity的状态及与activity相关的任务, ...
- 两个变量交换的四种方法(Java)
对于两种变量的交换,我发现四种方法,下面我用Java来演示一下. 1.利用第三个变量交换数值,简单的方法. (代码演示一下) class TestEV //创建一个类 { public static ...
- IOS开发之—— 在AFN基础上进行的网络请求的封装
网络请求的思路:如果请求成功的话AFN的responseObject就是解析好的. 1发送网络请求:get/post/或者别的 带上URL,需要传的参数 2判断后台网络状态码有没有请求成功: 3 请求 ...