I'm in trouble with seneca and seneca-web. I'm a really a beginner.
This is my code so far:
"use strict";
var express = require('express');
var Web = require("seneca-web");
var bodyParser = require('body-parser')
var plugin = require('./products_actions/products_actions');
module.exports = plugin;
var entities = require('seneca-entity')
var seneca = require('seneca')();
seneca.use(plugin);
seneca.use(entities);
seneca.use('mysql-store', {
name : 'ecrm',
host : 'localhost',
user : 'root',
password : 'ecrm',
port : 3306
})
seneca.ready(function(err) {
var Routes = [ {
pin : 'area:product,action:fetch,criteria:*',
prefix : '/products/fetch',
map : {
byId : {
GET : true,
suffix : "/:id"
}
}
}, {
pin : 'area:product,action:*',
prefix : '/products',
map : {
fetch : {
GET : true
},
add : {
GET : false,
PUT : true
}
}
} ];
var app = express();
app.use(bodyParser.json());
var config = {
routes : Routes,
adapter : require('seneca-web-adapter-express'),
context : app,
options : {
parseBody : false
}
}
seneca.use(Web, config);
app.listen(3000);
});
and here is the code where are defined the seneca actions:
module.exports = function(options) {
var seneca = this;
// ADD
seneca.add({
area : "product",
action : "add"
}, function(req, done) {
var products = this.make$("prodotti");
var args = req.args.body;
console.log(args);
products.nome = args.nome;
products.categoria = args.categoria;
products.descrizione = args.descrizione;
products.prezzo = args.prezzo;
products.save$(function(err, product) {
done(err, products.data$(false));
});
});
// get by Id , PROBLEM!!!
seneca.add({
area : "product",
action : "fetch",
criteria : "byId"
}, function(req, done) {
console.log("HERE");
var id = req.args.params.id;
var product = this.make("prodotti");
product.load$(id, done);
});
// LIST ALL
seneca.add({
area : "product",
action : "fetch"
}, function(args, done) {
var products = this.make("prodotti");
products.list$({}, done);
});
}
The problem is in the getbyId handler (route /products/fetch/byId/id_of_the product).
The code so far works but I want to get the id variable represented by id_of_the product not doing var id = req.args.params.id; but I want it merged in the req object and I would like to do var id = req.id;
The same in the ADD handler, I did var args = req.args.body; but I would like to see the body merged in the req object as I've seen in the book 'Developing Microservices in node.js' by David Gonzales.
The problem arises when in a handler I want to call another seneca action passing the id of the product. In that case the id is available to the req object and not in the url parameters. Of course I could test if the variable is defined in req.args.params and if not use the one from the req object but it's not a clean solution.
Is this possible with the current version of seneca and seneca web? I have installed them from npm and I have these versions: seneca 3.2.2 and seneca-web 2.0.0;
Thanks in advance!
You should marshal out the information you are interested, verify it's validity and call the underlying action with just that information. The role:web
can be a good gatekeeper for general sanity checks from user input prior to hitting your actual services.
Remember that the user can pass anything as that route parameter, body, querystring, etc. one must take care to sanitize user-provided information and only send valid information into the underlying actions.
seneca.add('role:web,domain:product,action:getById', function (msg, done) {
const id = parseInt(msg.args.params.id, 10)
if (isNaN(id)) {
return done(new Error('needs to be numeric'))
}
seneca.act('role:entity,domain:product,action:getById', {id}, done)
})
seneca.add('role:entity,domain:product,action:getById', function (msg, done) {
this.make$('product').load$(msg.id, done)
})
Retrieving information about the request from (in example above) msg.args
is the name of the game in seneca-web
- it's the only way to get at that information.