Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 14 additions & 12 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,5 @@
version: '3'
services:
facade:
build: ./services/facade
image: loopback-example-facade/facade
ports:
- "3000:80"
links:
- customer
networks:
app-net:
aliases:
- facade
- account-service
customer:
build: ./services/customer-service
image: loopback-example-facade/customer-service
Expand Down Expand Up @@ -39,6 +27,20 @@ services:
app-net:
aliases:
- transaction-service
facade:
build: ./services/facade
image: loopback-example-facade/facade
ports:
- "3000:80"
links:
- customer
- account
- transaction
networks:
app-net:
aliases:
- facade
- account-facade

networks:
app-net:
Expand Down
1 change: 1 addition & 0 deletions services/facade/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"posttest": "npm run lint && nsp check"
},
"dependencies": {
"bluebird": "latest",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do not depend on latest. Always use ^x.y.z, "bluebird": "^3.5.0" in this particular case.

If you depend on latest and a new major version of your dependency is released, your application is very likely to break, because a new major version typically has backwards-incompatible changes.

"compression": "^1.0.3",
"cors": "^2.5.2",
"helmet": "^1.3.0",
Expand Down
99 changes: 72 additions & 27 deletions services/facade/server/models/account.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,44 @@
'use strict';

const app = require('../server');
const promise = require('bluebird');

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are usually using Promise as the variable name.

const Promise = require('bluebird');


module.exports = function(Account) {
let accountService, customerService, transactionService;
let customerService, accountService, transactionService;

app.on('started', function() {
Account.getAccountSummary = function(accountNumber) {
let accountSummary = {};
return findAccountSummary({id: accountNumber, accountNumber: accountNumber})
.then(function(data) {
accountSummary = data.obj;
console.log("summary", accountSummary);
})
.then(function() {
return findAccount({id: accountNumber, accountNumber: accountNumber})
})
.then(function(data) {
accountSummary.account = data.obj;
console.log("account" , data.obj);
})
.then(function() {
return findCustomer({id: accountSummary.account.customerNumber, customerNumber: accountSummary.account.customerNumber})
})
.then(function(data) {
console.log(data);
accountSummary.customer = data.obj;
return accountSummary;
});
}

Account.listAllAccounts = function(customerNumber, cb) {
let findAccount = accountService.getFunction('Account', 'find');
findAccount({}, function(err, account) {
if (err) return cb(err);
cb(null, account.obj);
});
};

app.on('started', function(){
customerService = app.dataSources.Customer;
accountService = app.dataSources.Account;
transactionService = app.dataSources.Transaction;
Expand All @@ -14,36 +47,48 @@ module.exports = function(Account) {
transactionService.getFunction = getFunction;
});

function getFunction(model, method) {
let functionName = model + '_' + method;
return this.createModel(model, {})[functionName];
function findTransaction(input) {
let find = transactionService.getFunction('Transaction', 'findById');
return new Promise(function (resolve, reject) {
find(input, function(err, data) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is sort of an anti-pattern in Bluebird, use promisify instead - see http://bluebirdjs.com/docs/api/promise.promisify.html

if (err) return reject(new Error(err));
resolve(data);
});
});
}

Account.getAccountSummary = function(accountNumber, cb) {
let findCustomer = customerService.getFunction('Customer', 'findById');
let findAccount = accountService.getFunction('Account', 'findById');
let findAccountSummary = accountService.getFunction('AccountSummary', 'findById');
let findTransaction = transactionService.getFunction('Transaction', 'findById');
findAccountSummary({id: accountNumber, accountNumber: accountNumber}, function(err, accountSummary) {
if (err) return cb(err);
accountSummary = accountSummary.obj;
findAccount({id: accountNumber, accountNumber: accountNumber}, function(err, account) {
if (err) return cb(err);
findCustomer({id: account.obj.customerNumber, customerNumber: account.obj.customerNumber}, function(err, customer) {
if (err) return cb(err);
accountSummary.customer = customer.obj;
accountSummary.account = account.obj;
cb(null, accountSummary);
});
function findAccountSummary(input) {
let find = accountService.getFunction('AccountSummary', 'findById');
return new Promise(function (resolve, reject) {
find(input, function(err, data) {
if (err) return reject(new Error(err));
resolve(data);
});
});
}

Account.listAllAccounts = function(customerNumber, cb) {
let findAccount = accountService.getFunction('Account', 'find');
findAccount({}, function(err, account) {
if (err) return cb(err);
cb(null, account.obj);
function findAccount(input) {
let find = accountService.getFunction('Account', 'findById');
return new Promise(function (resolve, reject) {
find(input, function(err, data) {
if (err) return reject(new Error(err));
resolve(data);
});
});
};
}

function findCustomer(input) {
let find = customerService.getFunction('Customer', 'findById');
return new Promise(function (resolve, reject) {
find(input, function(err, data) {
if (err) return reject(new Error(err));
resolve(data);
});
});
}

function getFunction(model, method) {
let functionName = model + '_' + method;
return this.createModel(model, {})[functionName];

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC, this is the single place where you are looking up callback-based functions. In which case this is the place where you can promisify the function before you return it back.

return Promise.promisify(this.createModel(model, {})[functionName]);

However, this will not work for functions that expect this to be set. Here is a better solution:

function getFunction(modelName, methodName) {
  const functionName = modelName + '_' + methodName;
  const model = this.createModel(modelName, {});
  const method = Promise.promisify(model[functionName]);
  return method.bind(model);
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, this should not be needed once strongloop/loopback-connector-swagger#25 is landed and released.

}
};