Использование Grunt to Mock Endpoints

Я использую Yeoman, Grunt и Bower, чтобы построить платформу для построения интерфейса независимо от бэкэнда. Идея заключалась бы в том, что весь мой (AngularJS) контроллер, службы, фабрики и т.д. Живут в этом проекте и затем вводятся в мою серверную кодовую базу, основываясь на результате сборки grunt.

Мой вопрос:

Как я могу обмануть конечные точки, чтобы сервер Grunt откликнулся на те же конечные точки, что и мое (Rails) приложение?

В данный момент я использую:

 angular.module('myApp', ['ngResource'])

 .run(['$rootScope', function ($rootScope) {
     $rootScope.testState = 'test';
  }]);

И затем в каждой из моих индивидуальных услуг:

   mockJSON = {'foo': 'myMockJSON'}

И по каждому методу:

   if($rootScope.testState == 'test'){
    return mockJSON;
  }
  else {
    real service logic with $q/$http goes here
  }

Затем после grunt build удаляется testState = 'test'.

Это явно относительно сумасшедшая архитектура. Как я могу избежать этого? Как я могу заставить Grunt отвечать на те же конечные точки, что и мое приложение (некоторые из которых имеют динамические параметры) применяют некоторую логику (если необходимо) и служат для json файла (возможно, зависящего от параметров пути)?

Ответ 1

Я исправил эту проблему, используя экспресс, чтобы написать сервер, который отвечает статическим json.

Сначала я создал каталог в моем проекте под названием "api". Внутри этого каталога у меня есть следующие файлы:

package.json:

   {
     "name": "mockAPI",
     "version": "0.0.0",
     "dependencies": {
        "express": "~3.3.4"
      }
   }

Затем я запускаю npm install в этом каталоге.

index.js:

    module.exports = require('./lib/server');

lib/server.js:

    express = require('express');
    var app = express();

    app.get('/my/endpoint', function(req, res){
        res.json({'foo': 'myMockJSON'});
   });

    module.exports = app

и, наконец, в моем глобальном Gruntfile.js:

         connect: {
            options: {
               port: 9000,
               hostname: 'localhost',
            },
            livereload: {
              options: {
                 middleware: function (connect, options) {
                   return [
                     lrSnippet,
                     mountFolder(connect, '.tmp'),
                     mountFolder(connect, yeomanConfig.app),
                     require('./api')
                   ];
               }
            }
         },

Затем службы выполняют запросы, а экспресс-сервер обслуживает правильный JSON.

После grunt build, экспресс-сервер просто заменяется сервером rails.

Ответ 2

Начиная с grunt-contrib-connect v.0.7.0, вы также можете просто добавить свое настраиваемое промежуточное программное обеспечение в существующий стек промежуточного программного обеспечения без необходимости вручную восстанавливать существующий стек промежуточного программного обеспечения.

livereload: {
    options: {
        open: true,
        base: [
            '.tmp',
            '<%= config.app %>'
        ],
        middleware: function(connect, options, middlewares) {
            // inject a custom middleware into the array of default middlewares
            middlewares.push(function(req, res, next) {
                if (req.url !== '/my/endpoint') {
                    return next();
                }
                res.writeHead(200, {'Content-Type': 'application/json' });
                res.end("{'foo': 'myMockJSON'}");
            });
            return middlewares;
        }
    }
},

См. https://github.com/gruntjs/grunt-contrib-connect#middleware для официальной документации.

Ответ 3

В качестве альтернативы вы можете использовать grunt-connect-proxy, чтобы проксировать все, что отсутствует на вашем тестовом сервере, на фактический сервер.

Это довольно просто установить, только одна вещь, которую нужно помнить при добавлении прокси-сервера к промежуточному программному обеспечению, связанному с пересылкой в ​​реестре, - это добавить его последним, например:

middleware: function (connect) {
    return [
        lrSnippet,
        mountFolder(connect, '.tmp'),
        mountFolder(connect, yeomanConfig.app),
        proxySnippet
    ];
}

Ответ 4

grunt-connect-prism аналогичен проекту Ruby VCR. Он предоставляет простой способ для разработчиков переднего плана записывать ответы HTTP, возвращаемые их API (или другим удаленным исходным кодом), и воспроизводить их позже. Это, в основном, кеш HTTP, но для разработчиков, работающих с одним страничным приложением (SPA). Вы также можете создавать заглушки для вызовов API, которые не существуют, и заполнять их так, как вы хотите.

Он полезен для издевательства сложных вызовов API с высокой задержкой во время разработки. Это также полезно при написании тестов e2e только для вашего SPA, удаление сервера из уравнения. Это приводит к значительно более быстрому выполнению вашего тестового пакета e2e.

Призма работает, добавляя настраиваемое связующее ПО для подключения к серверу подключения, предоставляемого плагином grunt-contrib-connect. В режиме "записи" он будет генерировать файл за ответ в файловой системе с содержимым следующего содержания:

  {
    "requestUrl": "/api/ponies",
    "contentType": "application/json",
    "statusCode": 200,
    "data": {
      "text": "my little ponies"
    }
  }

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Я являюсь автором этого проекта.

Ответ 5

Вы можете использовать прокси-сервер Apache и подключить сервер REST с помощью gruntjs.

Apache сделает следующее: прокси /- > gruntjs proxy/service → сервер REST


вы использовали бы приложение, попавшее в Apache, и приложение angular.js подумало бы, что разговаривает с самим собой, поэтому проблема с перекрестным доменом отсутствует.

Вот отличный учебник по настройке: http://alfrescoblog.com/2014/06/14/angular-js-activiti-webapp-with-activiti-rest/

Ответ 7

Просто мой альтернативный способ, основанный на ответе Авраама Р. Это не нужно устанавливать экспресс в папке "api". Я могу отделить макетные сервисы для определенных файлов. Например, моя папка "api" содержит 3 файла:

апи\

  • index.js//присваиваем все "модули", а затем просто требуем этого.
  • user.js//все насмешливые для пользователя
  • product.js//все насмехающиеся за продукт

file user.js

var user = function(req, res, next) {
if (req.method === 'POST' && req.url.indexOf('/user') === 0) {
     res.end(
          JSON.stringify({
                    'id' : '5463c277-87c4-4f1d-8f95-7d895304de12',
                    'role' : 'admin'
            })
         );
    }
    else {
        next();
    }
}
module.exports = user;

file product.js

var product = function(req, res, next) {
if (req.method === 'POST' && req.url.indexOf('/product') === 0) {
     res.end(
          JSON.stringify({
                    'id' : '5463c277-87c4-4f1d-8f95-7d895304de12',
                    'name' : 'test',
                    'category': 'test'
            })
         );
    }
    else {
        next();
    }
}
module.exports = product;

index.js просто назначает все "модули", и мы просто требуем этого.

module.exports = {
    product: require('./product.js'),
    user: require('./user.js')
};

Мой файл Gruntfile.js

 connect: {
      options: {
        port: 9000,
        // Change this to '0.0.0.0' to access the server from outside.
        hostname: 'localhost',
        livereload: 35729
      },
      livereload: {
        options: {
          open: true,
          middleware: function (connect) {

            return [
              connect.static('.tmp'),
              connect().use(
                '/bower_components',
                connect.static('./bower_components')
              ),
              connect.static(appConfig.app),
              require('./api').user,
              require('./api').product,
            ];
          }
        }
      }