I have been making an API server with feathers. I have two mongoose services. Now my requirement is I want one API that has a result of both services. Let's say product-master and product are two services. The output I want is to merge both services.
To accomplish this I found one way is hook. So I tried this.
module.exports = function () {
return function (hook) {
let Product = hook.app.service('product').Model;
return new Promise(function(resolve, reject){
Product.find({}, function(err, products) {
var productMap = [];
products.forEach(function(product) {
productMap.push(products);
});
res.send(productMap);
console.log(productMap);
resolve(hook);
});
});
};
};
Now I called the hook on before find method of product-master But I don't understand how to merge the records of product to product-master service.
And one more thing is how to create a one different API that has a merged result and custom route like http://localhost:3030/products.
Update
I found one post on stackoverflow, this might be helpful.
There are different ways for what I think you want to do. I also recommend not using the models directly but the services you want (by calling their service methods). You also want to be familiar with the API for hooks. Then you have some options:
1) Modifying the existing results
To modify the result of an existing service call, modify hook.result
in an after
hook:
module.exports = function () {
return function (hook) {
let productService = hook.app.service('product');
return productService.find({
paginate: false // Turn off pagination
}).then(products => {
hook.result.products = products;
return hook;
});
};
};
Then
const myHook = require('../../hooks/myhook');
app.service('products-master').hooks({
after: {
get: [ myHook() ]
}
});
This will add a products
property when getting a single item from the products-master
service.
2) Setting hook.result
To skip a database call you can set hook.result
to what you want to return in a before
hook. Keep in mind that all after
hooks will still run.
3) Using a custom service
In a custom service you can do whatever you like, for example get all the things you need and put them together manually:
app.use('/all-products', {
find() {
return this.app.service('products-master').find(params).then(page => {
const promises = page.data.map(masterProduct => {
return this.app.service('products').find({
paginate: false,
query: {
masterProductId: masterProduct._id
}
}).then(products => {
// Add to masterProduct
masterProduct.products = products;
});
});
return Promise.all(promises).then(() => {
// Return `page` which has the modified data
return page;
});
});
},
setup(app) {
this.app = app;
}
});
In the generator a custom service can be created by choosing custom service
and modifying the servicename.class.js
.
4) The populate hook
Since I think you just want to populate related entities you can also have a look at the populate common hook. It can do those things automatically.
5) Using Mongoose $populate
The Mongoose Feathers adapter also supports the $populate query parameter which allows you to pull in relationships that you defined in your Mongoose model.
For more information on associations in Feathers also see this FAQ.