[Перевод] Разработка REST API на Express, Restify, hapi и LoopBack

Если вы работаете над Node.js приложением, то есть все шансы, что у него появится некое API, которое будет использовано вами или кем-то другим. Наверняка это будет REST API и перед вами возникнет дилемма — какие инструменты и подходы использовать. Ведь выбор так широк…image

Благодаря невероятно активному сообществу Node.js, количество результатов на NPM по запросу «rest» зашкаливает. У каждого есть свои реализации и подходы, но у некоторых есть что-то общее в создании REST API на Node.js.

Express Наиболее распространённый подход — дать доступ к ресурсам с помощью Express. Это даст лёгкий старт, но в последствии будет становиться всё более тяжелым.Пример Используя Router последней версии Express 4.x, ресурс будет выглядеть примерно так: 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 — это практически стандарт Node.js-приложения. Полная кастомизация. Все ресурсы необходимо создавать вручную и, в результате, появится много повторного кода или хуже — собственная библиотека. Каждый ресурс требует тестирования или простой проверки на 500-ую ошибку. Рефакторинг станет болезненным, так как будет необходимо править всё и везде. Нету стандартного подхода, нужно искать свой. Express — это отличный старт, но в итоге вы почувствуете боль от «своего собственного» подхода.Restify Restify — относительно старый игрок на поле Node.js API, но очень стабильный и активно разрабатываемый. Он создан для построения правильных REST-сервисов и намеренно похож на Express.Пример Так как он похож на 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); Плюсы Минусы Поддержка DTrace, если API работает на платформе, которая его поддерживает. Нет такого лишнего функционала, как шаблоны и рендеринг. Ограничение частоты запросов (throttling). Поддержка SPDY Минусы такие же как и у 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, то они могут стать плохим выбором.487947fb45eefe3ab5cff01ad161fdef.pngLoopBack 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} imageЧтобы легко изучить свой API, достаточно подключить встроенный модуль explorer:

var explorer = require ('loopback-explorer'); app.use ('/explorer', explorer (app, {basePath: '/api'})); Теперь откройте localhost:8080/explorer и получите эту крутую документацию: image

Пример на 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» } image

Плюсы Минусы Очень быстрая разработка REST API. Договорённость в конфигурации. Встроенные готовые модели. Поддержка RPC. Полностью настраиваемый. Обширная документация. Команда, работающая над проектом на постоянной основе и являющаяся основной компанией-контрибутором в Node.js. Коммерческая поддержка. Порог вхождения немного высок, так как фреймворк состоит из множества деталей. Что дальше

© Habrahabr.ru