Если вы работаете над Node.js приложением, то есть все шансы, что у него появится некое API, которое будет использовано вами или кем-то другим. Наверняка это будет REST API и перед вами возникнет дилемма — какие инструменты и подходы использовать. Ведь выбор так широк…
Благодаря невероятно активному сообществу Node.js, количество результатов на NPM по запросу «rest» зашкаливает. У каждого есть свои реализации и подходы, но у некоторых есть что-то общее в создании REST API на Node.js.
Express
Наиболее распространённый подход — дать доступ к ресурсам с помощью Express. Это даст лёгкий старт, но в последствии будет становиться всё более тяжелым.
var express = require('express');
var Item = require('models').Item;
var app = express();
var itemRoute = express.Router();
itemRoute.param('itemId', function(req, res, next, id) {
Item.findById(req.params.itemId, function(err, item) {
req.item = item;
next();
});
});
itemRoute.route('/:itemId')
.get(function(req, res, next) {
res.json(req.item);
})
.put(function(req, res, next) {
req.item.set(req.body);
req.item.save(function(err, item) {
res.json(item);
});
})
.post(function(req, res, next) {
var item = new Item(req.body);
item.save(function(err, item) {
res.json(item);
});
})
.delete(function(req, res, next) {
req.item.remove(function(err) {
res.json({});
});
})
;
app.use('/api/items', itemRoute);
app.listen(8080);
Плюсы | Минусы |
---|---|
|
|
Express — это отличный старт, но в итоге вы почувствуете боль от «своего собственного» подхода.
Restify
Restify — относительно старый игрок на поле Node.js API, но очень стабильный и активно разрабатываемый. Он создан для построения правильных REST-сервисов и намеренно похож на Express.
var restify = require('restify');
var Item = require('models').Item;
var app = restify.createServer()
app.use(function(req, res, next) {
if (req.params.itemId) {
Item.findById(req.params.itemId, function(err, item) {
req.item = item;
next();
});
}
else {
next();
}
});
app.get('/api/items/:itemId', function(req, res, next) {
res.send(200, req.item);
});
app.put('/api/items/:itemId', function(req, res, next) {
req.item.set(req.body);
req.item.save(function(err, item) {
res.send(204, item);
});
});
app.post('/api/items/:itemId', function(req, res, next) {
var item = new Item(req.body);
item.save(function(err, item) {
res.send(201, item);
});
});
app.delete('/api/items/:itemId', function(req, res, next) {
req.item.remove(function(err) {
res.send(204, {});
});
});
app.listen(8080);
Плюсы | Минусы |
---|---|
|
Минусы такие же как и у Express — много лишней работы. |
hapi
hapi — менее известный фреймворк, который разрабатывается командой Walmart Labs. В отличие от Express и Restify у него несколько другой подход, предоставляющий больший функционал сразу из коробки.
var Hapi = require('hapi');
var Item = require('models').Item;
var server = Hapi.createServer('0.0.0.0', 8080);
server.ext('onPreHandler', function(req, next) {
if (req.params.itemId) {
Item.findById(req.params.itemId, function(err, item) {
req.item = item;
next();
});
}
else {
next();
}
});
server.route([
{
path: '/api/items/{itemId}',
method: 'GET',
config: {
handler: function(req, reply) {
reply(req.item);
}
}
},
{
path: '/api/items',
method: 'PUT',
config: {
handler: function(req, reply) {
req.item.set(req.body);
req.item.save(function(err, item) {
res.send(204, item);
});
}
}
},
{
path: '/api/items',
method: 'POST',
config: {
handler: function(req, reply) {
var item = new Item(req.body);
item.save(function(err, item) {
res.send(201, item);
});
}
}
},
{
path: '/api/items/{itemId}',
method: 'DELETE',
config: {
handler: function(req, reply) {
req.item.remove(function(err) {
res.send(204, {});
});
}
}
}
]);
server.start();
Плюсы | Минусы |
---|---|
|
hapi, также как Express и Restify, даёт отличные возможности, но как их использовать, вы должны понять сами. |
Express, Restify и hapi отличные решения для старта, но, если вы планируете развивать API, то они могут стать плохим выбором.
LoopBack
LoopBack от StrongLoop — это полноценный Node.js-фреймворк для соединения приложений с данными через REST API. Он перенимает мантру "договорённость в конфигурации", ставшей популярной в Ruby on Rails.
Пример
var loopback = require('loopback');
var Item = require('./models').Item;
var app = module.exports = loopback();
app.model(Item);
app.use('/api', loopback.rest());
app.listen(8080);
Много волшебства происходит за кулисами, но всего шесть строчек кода создадут для вас эти ресурсы:
GET /items
GET /items/count
GET /items/findOne
GET /items/{id}
GET /items/{id}/exists
POST /items
PUT /items
PUT /items/{id}
DELETE /items/{id}
Чтобы легко изучить свой API, достаточно подключить встроенный модуль explorer:
var explorer = require('loopback-explorer');
app.use('/explorer', explorer(app, {basePath: '/api'}));
Теперь откройте localhost:8080/explorer и получите эту крутую документацию:
Пример на LoopBack достаточно простой, но что на счёт RPC-ресурса?
var loopback = require('loopback');
var explorer = require('loopback-explorer');
var remoting = require('strong-remoting');
var Item = require('./models').Item;
var app = module.exports = loopback();
var rpc = remoting.create();
function echo(ping, callback) {
callback(null, ping);
}
echo.shared = true;
echo.accepts = {arg: 'ping'};
echo.returns = {arg: 'echo'};
rpc.exports.system = {
echo: echo
};
app.model(Item);
app.use('/api', loopback.rest());
app.use('/explorer', explorer(app, {basePath: '/api'}));
app.use('/rpc', rpc.handler('rest'));
app.listen(8080);
Теперь можно делать так:
$ curl "http://localhost:8080/rpc/system/echo?ping=hello"
{
"echo": "hello"
}
Плюсы | Минусы |
---|---|
|
Порог вхождения немного высок, так как фреймворк состоит из множества деталей. |
Что дальше
- Установите LoopBack через npm.
- Почитайте документацию.
- Если вам нужны кластеринг Node.js-приложений и мониторинг производительности, попробуйте StrongOps.
Автор: javascript