Когда дело доходит до разработки Node.js, мы должны упомянуть два самых популярных фреймворка: express и koa. Express существует уже некоторое время и представляет собой краткую и гибкую среду веб-разработки, простую в использовании и мощную. Koa относительно молод, это гибкий фреймворк для разработки, переработанный оригинальной командой Express framework на основе новых функций ES6.
И Express, и koa являются средами разработки на стороне сервера.При разработке на стороне сервера основное внимание уделяется инкапсуляции и обработке объектов HTTP-запросов и HTTP-ответов, обслуживанию жизненного цикла приложения и обработке представлений. Следующее будет в основном через эти аспекты, сравнение двух будет введено, чтобы увидеть, в чем разница.
Express в основном основан на фреймворке промежуточного программного обеспечения Connect, который богат функциями и может быть использован в любое время, а сам фреймворк инкапсулирует большое количество удобных функций, таких как маршрутизация, обработка представлений и так далее. koa в основном основан на платформе промежуточного программного обеспечения.Сама структура не включает в себя множество функций.Большинство функций должны выполняться пользователями, которым требуется промежуточное программное обеспечение.Однако благодаря механизму промежуточного программного обеспечения, основанному на функции генератора ES6, он решает долгие - критикуют «ад обратных вызовов» и хлопотную обработку ошибок, что очень нравится разработчикам.
Экспресс и коа первые впечатления
Сначала приезжайте в Hello World, давайте познакомимся друг с другом
//Express
var express = require('express')
var app = express() //创建一个APP实例
//建一个项目根目录的get请求路由,回调方法中直接输出字符串Hello World!
app.get('/', function (req, res) {
res.send('Hello World!')
});
//监听端口,启动服务
app.listen(3000);
//Koa
var koa = require('koa');
var route = require('koa-route'); //koa默认没有集成route功能,引入中间件
var app = koa(); //创建一个APP实例
//建一个项目根目录的get请求路由,回调方法中直接输出字符串Hello World!,就是挂载一个中间件
app.use(route.get('/', function *(){
this.body = 'Hello World';
}));
//监听端口,启动服务
app.listen(3000);
Видно, что создание базовой веб-службы очень просто, и можно сказать, что несколько строк кода решают проблему. Написание этих двух в основном одинаково, самая большая разница заключается в том, что экспресс-обработка маршрутов интегрирована, в то время как KOA необходимо ввести промежуточное программное обеспечение. Ниже приводится отличие официального документа KOA для обеих функций:
Сравнение важных функций
Feature | Koa | Express | Connect |
---|---|---|---|
Middleware Kernel | |||
Routing | |||
Templating | |||
Sending Files | |||
JSONP |
При последующем сравнении вы можете увидеть, что, хотя koa, кажется, интегрирует множество функций меньше, чем экспресс, в основном он используется одинаково, потому что промежуточное программное обеспечение очень богатое и всеобъемлющее, и требуется то, что требуется (не обязательно как экспресс). Сначала нужна помощь), но он более гибкий в использовании.
Жизненный цикл приложения и контекст
В процессе проекта нам часто приходится использовать объекты конфигурации и данных, которые являются общими на протяжении всего жизненного цикла приложения, такие как URL-адрес службы, необходимость включения функции, конфигурация интерфейса, текущие данные пользователя и т. д. Это относительно простые функции. Обе очень удобны. Контекст приложения koa кажется более удобным в использовании.
//Express
//共享配置,express提供了很多便利的方法
app.set('enableCache', true)
app.get('enableCache')//true
app.disable('cache')
app.disabled('cache')//true
app.enable('cache')
app.enabled('cache')//true
//应用共享数据:app.locals
app.locals.user = {name:"Samoay", id:1234};
//Koa
//配置,直接使用koa context即可
app.enableCache = true;
app.use(function *(next){
console.log(this.app.enableCache);
//true
this.app.enableCache = false;
//just use this
this.staticPath = 'static';
yield *next;
});
//应用共享数据:ctx.state
this.state.user = {name:"Samoay", id:1234};
запрос HTTP-запрос
Что нужно обрабатывать на стороне сервера, как обрабатывать и какие параметры обрабатывать — все зависит от запроса, отправленного клиентом.Оба фреймворка инкапсулируют объект HTTP Request, что удобно для обработки этой части. Следующие основные примеры иллюстрируют обработку параметров запроса.Для получения другой информации, такой как информация заголовка и файлы cookie, обратитесь к официальной документации. Между ними нет большой разницы, за исключением небольшой разницы в написании. GET-параметры можно получить напрямую через объект Request, а POST-параметры нужно сначала разобрать, внедрив промежуточное ПО, а потом уже получить значение.
// Express
// 获取QueryString参数
// GET /shoes?order=desc&shoe[color]=blue
req.query.order
// => "desc"
req.query.shoe.color
// => "blue"
// 通过路由获取Restful风格的URL参数
app.get('/user/:id?', function userIdHandler(req, res) {
console.log(req.params.id);
res.send('GET');
})
//获取POST数据:需要body-parser中间件
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
app.post('/', function (req, res) {
console.log(req.body);
res.json(req.body);
})
// 获取QueryString参数
// GET /?action=delete&id=1234
this.request.query
// => { action: 'delete', id: '1234' }
// 通过路由获取Restful风格的URL参数
var route = require('koa-route');
app.use(route.get('/post/:id', function *(id){
console.log(id);
// => 1234
}));
// 获取POST数据:需要co-body中间件
// Content-Type: application/x-www-form-urlencoded
// title=Test&content=This+is+a+test+post
var parse = require('co-body');
app.use(route.post('/post/new', function *(){
var post = yield parse(this.request);//this
console.log(post);
// => { title: 'Test', content: 'This is a test post' }
}));
Маршрут Маршрут
После получения запроса клиента служба должна выполнить другую обработку, определив метод запроса (метод HTTP: GET, POST, PUT...) и конкретный путь запроса (путь). Эта часть функции и есть то, чем должен заниматься Route, грубо говоря, это распределение запроса, который распределяется по разным callback-методам для обработки.
// Express
// app.all表示对所有的路径和请求方式都要经过这些回调方法的处理,可以逗号方式传入多个
app.all('*', authentication, loadUser);
// 也可以多次调用
app.all('*', requireAuthentication)
app.all('*', loadUser);
// 也可以针对某具体路径下面的所有请求
app.all('/api/*', requireAuthentication);
// app.get GET方式的请求
app.get('/user/:id', function(req, res) {
res.send('user ' + req.params.id);
});
// app.post POST方式的请求
app.post('/user/create', function(req, res) {
res.send('create new user');
});
Здесь необходимо объяснить два вопроса, первый из которыхapp.get
, в жизненном цикле приложения также естьapp.get
метод для получения конфигурации проекта. Экспресс внутри публичный метод, если передать только один параметр, то получается конфигурация, а два параметра обрабатываются как маршрут. С последующимapp.use('*', cb)
а такжеapp.all('*', cb)
Разница в том, что первый — это промежуточный метод, а вызовы последовательные и могут не выполняться, второй — метод маршрутизации, который обязательно будет выполнен.
// Koa
// 和Express不同,koa需要先引入route中间件
var route = require('koa-route');
//引入中间件之后支持的写法差不多,只是路径传入route,然后把route作为中间件挂载到app
app.use(route.get('/', list));
app.use(route.get('/post/new', add));
app.use(route.get('/post/:id', show));
app.use(route.post('/post', create));
//链式写法
var router = require('koa-router')();
router.get('/', list)
.get('/post/new', add)
.get('/post/:id', show)
.post('/post', create);
app.use(router.routes())
.use(router.allowedMethods());
Посмотреть Просмотры
Сама среда Express интегрирует функцию просмотра, предоставляет функцию консолидации.js, может быть практически любым механизмом шаблонов Javascript и предоставляет удобный метод для настройки просмотра. Koa необходимо представить промежуточное программное обеспечение для совместного просмотра, совместное представление также основано на консолидации.js, а возможности поддержки столь же мощны.
// Express
// 这只模板路径和默认的模板后缀
app.set('views', __dirname + '/tpls');
app.set('view engine', 'html');
//默认,express根据template的后缀自动选择模板
//引擎渲染,支持jade和ejs。如果不使用默认扩展名
app.engine(ext, callback)
app.engine('html', require('ejs').renderFile);
//如果模板引擎不支持(path, options, callback)
var engines = require('consolidate');
app.engine('html', engines.handlebars);
app.engine('tpl', engines.underscore);
app.get('list', function(res, req){
res.render('list', {data});
});
//Koa
//需要引入co-views中间件
var views = require('co-views');
var render = views('tpls', {
map: { html: 'swig' },//html后缀使用引擎
default: "jade"//render不提供后缀名时
});
var userInfo = {
name: 'tobi',
species: 'ferret'
};
var html;
html = render('user', { user: userInfo });
html = render('user.jade', { user: userInfo });
html = render('user.ejs', { user: userInfo });
вернуть HTTP-ответ
После того, как параметры запроса получены, конкретный запрос обработан и представление готово, пришло время вернуть его клиенту, который является объектом HTTP Response. Эта часть также относится к базовой части фреймворка, все они инкапсулированы и реализованы, существенное отличие состоит в том, что koa напрямую привязывает вывод к свойству ctx.body, а для вывода JSON или JSONP необходимо внедрять промежуточное ПО.
// Express
//输出普通的html
res.render('tplName', {data});
//输出JSON
res.jsonp({ user: 'Samoay' });
// => { "user": "Samoay" }
//输出JSONP ?callback=foo
res.jsonp({ user: 'Samoay' });
// => foo({ "user": "Samoay" });
//res.send([body]);
res.send(new Buffer('whoop'));
res.send({ some: 'json' });
res.send('<p>some html</p>');
//设定HTTP Status状态码
res.status(200);
//koa直接set ctx的status和body
app.use(route.get('/post/update/:id', function *(id){
this.status = 404;
this.body = 'Page Not Found';
}));
var views = require('co-views');
var render = views('tpls', {
default: "jade"//render不提供后缀名时
});
app.use(route.get('/post/:id', function *(id){
var post = getPost(id);
this.status = 200;//by default, optional
this.body = yield render('user', post);
}));
//JSON
var json = require('koa-json');
app.use(route.get('/post/:id', function *(id){
this.body = {id:1234, title:"Test post", content:"..."};
}));
ПО промежуточного слоя
Сравнивая использование нескольких основных функций фреймворка, на самом деле самая большая разница заключается в обработке промежуточного программного обеспечения. Поскольку Express предшествует функции ES6, основным принципом промежуточного программного обеспечения по-прежнему является метод обратного вызова, а koa выигрывает от функции генератора и фреймворка co (co будет инкапсулировать возврат всех генераторов в объекты Promise), что делает промежуточное программное обеспечение более удобным для написания. элегантный. .
// req 用于获取请求信息, ServerRequest 的实例
// res 用于响应处理结果, ServerResponse 的实例
// next() 函数用于将当前控制权转交给下一步处理,
// 如果给 next() 传递一个参数时,表示出错信息
var x = function (req, res, next) {
// 对req和res进行必要的处理
// 进入下一个中间件
return next();
// 传递错误信息到下一个中间件
return next(err);
// 直接输出,不再进入后面的中间件
return res.send('show page');
};
// koa 一切都在ctx对象上+generator
app.use(function *(){
this; // is the Context
this.request; // is a koa Request
this.response; // is a koa Response
this.req;// is node js request
this.res;// is node js response
//不再进入后面的中间件, 回溯upstream
return;
});
Эта статья подготовлена Технологической ассоциацией Alibaba (ATA).
Автор: Джин Хонг