2013-07-29 3 views
11

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

Мой вопрос:

Как я могу издеваться конечных точек, так что сервер 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-файлу (возможно, зависящему от параметров пути)?

ответ

14

Я исправил эту проблему, используя выражение, чтобы написать сервер, который отвечает статическим 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, экспресс-сервер просто заменяется сервером рельсов.

+1

Это прекрасно работает, но как я могу перезагрузить изменения в Lib/server.js без перезагрузки сервера? – pablomolnar

+0

Это не проблема. Я закончил работу с исправлением, так как изменения в lib/server довольно редко (его небольшая компания). Я бы абсолютно ЛЮБЛЮ, чтобы услышать ваше решение, если вы придумали один –

+2

@pablomolnar Плагин, который я написал (ответ ниже) позволяет изменять макетные ответы, пока сервер dev все еще работает. http://stackoverflow.com/a/25714447/895309 –

4

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

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

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

По 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 для официальной документации.

0

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

Apache будет делать это: прокси/-> gruntjs прокси/сервис -> REST сервер


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

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

2

grunt-connect-prism похож на проект Руби VCR. Он предоставляет простой способ для разработчиков переднего плана записывать ответы HTTP, возвращаемые их API (или другим удаленным исходным кодом), и воспроизводить их позже. Это, в основном, кеш HTTP, но для разработчиков, работающих с одним страничным приложением (SPA). You can also generate stubs for API calls that don't exist, and populate them the way you want.

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

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

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

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

0

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

Api \

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

файлу 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; 

файл 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.j s просто назначает все «модули», и мы просто требуем этого.

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, 
      ]; 
      } 
     } 
     } 
Смежные вопросы