Разработка REST API на Express, Restify, hapi и LoopBack

Автор оригинала: Alex Gorbatchev
  • Перевод
  • Tutorial
Если вы работаете над 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);


Плюсы Минусы
  1. Низкий порог вхождения, Express — это практически стандарт Node.js-приложения.
  2. Полная кастомизация.

  1. Все ресурсы необходимо создавать вручную и, в результате, появится много повторного кода или хуже — собственная библиотека.
  2. Каждый ресурс требует тестирования или простой проверки на 500-ую ошибку.
  3. Рефакторинг станет болезненным, так как будет необходимо править всё и везде.
  4. Нету стандартного подхода, нужно искать свой.

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);


Плюсы Минусы
  1. Поддержка DTrace, если API работает на платформе, которая его поддерживает.
  2. Нет такого лишнего функционала, как шаблоны и рендеринг.
  3. Ограничение частоты запросов (throttling).
  4. Поддержка 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();


Плюсы Минусы
  1. Полный контроль над приёмом запросов.
  2. Детальная справка с генерацией документации.

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}

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

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

Порог вхождения немного высок, так как фреймворк состоит из множества деталей.



Что дальше


Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Слышали ли вы раньше о LoopBack?

Пробовали ли вы работать с LoopBack?

Поделиться публикацией

Похожие публикации

AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 25

    0
    Интересно. А вы koa не пробовали?
      0
      Не пробовал, но сейчас пролистал их страницу и не смог найти что-то про REST API. Как он предназначен для этого?
        0
        Вроде как позиционируется как развитие expressjs
          +1
          Проблема только в том, что Express (как и Koa) — не API-фреймворк, API с его помощью делать можно, но это просто «HTTP-утилита», о чем и говорит сам создатель Express/Koa.
      +3
      Совсем недавно пытался найти самый привлекательный фреймфорк для REST API и наткнулся на sailjs. Можете про него что-нибудь сказать?
        0
        Выглядит интересно, правда ACL показался не настолько развитым как у LoopBack, что очень важно в комплексных проектах.
          0
          Sails на самом деле хорош и проверен — используйте его, и не пожалеете. LoopBack выглядит очень перспективно, но пока еще очень молодой. Можно реально использовать чистый Express/Koa, но тут я солидарен с автором — по мере роста проекта и количества функциональности, поддерживать будет все сложнее, а абстрагирование разных штук для исключения повторений приведет к «своему фреймворку» (скорее минус, чем плюс)
          +7
          Знаете, когда вы хотите пропиарить свою библиотеку совсем не обязательно это оборачивать в «псевдо-сравнительный анализ», да еще и с библиотеками с другим подходом, да еще и с тремя похожими. Лучше честно сказать — предлагаем другой подход или/и сделать акцент на легкости перехода с руби
            +4
            Слушайте, у вас классный фреймворк, позволяет мигрировать с express и проксировать вызовы в монго, а вы его так плохо пиарите :)
              0
              Не мой, я только контрибутил немного кода в mysql-connector.
              Но да, крутой и интересный :-)
              +1
              Это перевод, но я постараюсь передать этот совет Алексу Горбачёву.
              И если читателям LoopBack покажется интересным, то следующую статью сделать более детальной.
              +1
              Для экспресса сваггер тоже есть.
                0
                Какую магию нужно будет применять что бы отойти от REST в одном месте?
                0
                Можно ли вместо родных моделей использовать mongoose?
                  0
                  Не нашёл готового решения, но думаю можно легко написать конвертер.
                  Я использовал модели Ember.js и подгонял руками.
                  +1
                  Плять вот зла то не хватает, загляните уже наконец-то в examples хотя бы, чтобы после обсирать express. Плюсом есть куча независимых модулей которые гибко и просто расширяют функциональность express. И еще он на порядок быстрее предложенных фреймворков.
                    –2
                    Собственно, LoopBack тоже расширяет функциональность express.
                    Настолько, что ставшие типичными задачи решаются десятком строк кода.
                    0
                    Возможно, для некоторых, лучший выбор будет в пользу чистого connect с подключенными нужными middleware.
                      0
                      Да, конечно. Автор подчёркивает, что LoopBack для проектов с большим будущем.

                      Когда передо мной стоит задача сделать AJAX-вызов, то я отказываюсь от подключения jQuery в пользу десятка строк чистого JS.
                      +2
                      Один раз я довольно элегантно решил проблему маршрутизации в express.
                      Для маршрутов создавал небольшой json файл, а все перенаправление вообще получилось в несколько строк. Конечно json может не самый удачный формат, но мне не много путей описать надо было.

                      Но lookback выглядит интересным, только у него цели немного другие чем в express.
                        0
                        Мне нравится твоё решение, конфигурацию будет легко поддерживать.
                        LoopBack про REST API и он также основан на Express — надёжной базе для всего.
                          0
                          LoopBack про REST API и он также основан на Express — надёжной базе для всего.

                          Собственно, поэтому и не нужно было сравнивать Express и LoopBack (который расширяет Express). Достаточно было просто написать, что LoopBack добавляет отличную (кстати, на самом деле) прослойку функциональности и соглашений для быстрого построения REST-API.
                        +2
                        Статью следует переименовать «Почему LoopBack лучший REST API фреймворк для NodeJS»
                          0
                          Отличное название для следующей статьи, не перевода :-)

                        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                        Самое читаемое