I have a custom logging function which is assigned to express requests req.log object using middleware.
The purpose of this is for the logging funtion to be able to read the request headers.traceid, before transmitting the log event to a seperate service.
This is working perfectly fine using middlware or with an extra parameter in the function, however to simplify the use of it.
What I'd really like to know if there's a way for the function to be able to read the req object from the scope it was called in, without referencing it either using middlware or as a function paramter?
// log.js
module.exports = () => {
console.log(...arguments)
const req = getVarFromParentScope("req") || undefined
const traceId = req?.headers.traceid || null
// POST { timestamp, traceId, args: { ...arguments } } to logging service
}
No, it isn't.
(And if it was, then the ability for a function to access a variable inside another function just because it was the calling function would make it very easy to write code that was very hard to debug.)
Related
I'm trying to decide on a consistent response JSON structure and I found this SO answer.
I like the simplicity of JSend but now I'm wondering what is a clean way to implement that structure in express without having to manually create it each response or use a constructor in every controller method to help build the structure. I found jsend-express npm but it has so few downloads I'm worried about relying on it.
Can anyone recommend some ways to automatically enforce some of this structure in express myself?
However, I'm not sure why a status key is even necessary when the 3 states seem to already be covered by HTTP statuses and I don't see this key recommended in google's style guide, so that's another reason I may not want to use the jsend package and just do it myself to omit some keys and add later if needed.
This ended up being how I did it based on this SO answer.
I have a catch all error handler that adds the error key, but for all non-errors I wanted the data to be wrapped in a data key without having do it in every controller method by hand, or to call another function in every controller method before the res.json since that is also repetitive.
/**
* Nests all successful res data in a `data` key. Any additional meta-data
* that needs to be present at the top level json object can be added here.
* #param {request} _req
* #param {response} res
*/
const modifyResponseBody = (_req, res, next) => {
const resDotJson = res.json;
res.json = function (data) {
const isError = data?.hasOwnProperty?.("error") === true;
if (!isError) {
arguments[0] = { data: data };
}
resDotJson.apply(res, arguments);
};
next();
};
app.use(modifyResponseBody);
A logger is implemented as a middle-ware. Need to access the output of the logger through another dialog.
Look at the Botbuilder-Samples repo, the 17.multilingual-conversations sample. It demonstrates how you can interact with the dialog by receiving and sending activities based around the current context and inputs.
First, assign your middleware to the adapter in the index.js file:
const { LoggerMiddleware } = require('./logger-middleware');
adapter.use(new LoggerMiddleware (parameter_1, parameter_2));
Like the translator-middleware.js file, you will want to pass any necessary parameters thru the constructor of your middleware file:
constructor(parameter_1, parameter_2) {
this.parameter_1 = parameter_1;
this.parameter_2 = parameter_2;
}
After which, you create the onTurn method (and any associated methods), passing in the context and utilizing the class constructor parameters you need. Here you can create new dialogs that make use of the passed in logged data.
async onTurn(turnContext, next) {
let loggerText = this.parameter_1;
[...do stuff with <loggerText> data...]
await next();
}
In many respects, the middleware looks and functions like your main bot.js file. It is simply called at a different point in the process.
Hope of help.
I'm trying to create a simple validator in my feathersjs app and I need to have access to hook.app so I can retrieve the users service and check for uniqueness. Below is my code
checkUniqueEmail = (values, hook) => {
const userService = hook.app.service('users');
//below is my validation
}
The problem is that the hook variable is returning undefined instead of the hook object. The feathers-hooks-common github code it shows that this should be possible since hook is being pass as the 2nd parameter. (see below)
const results = validator(getItems(hook), hook); // line 18
I'm not sure what I'm doing wrong here.
I found a good documentation about feathers-hooks-common validate. It is better explained here. https://eddyystop.gitbooks.io/feathers-docs-common/content/hooks/validation.html
all you need to do is at create hook
//pass context or hook
create:[
validate((values,context) =>validations.signupAsync(values,context))
]
//at validations.signupAsync
clientValidations.signupAsync = (values,context) => {
const userService= context.app.service('users')
}
There is a generic structure of nodejs callback functions :
function(req,res){
//handle callback
}
I just want, callback should work correctly even if sometimes i write in mistake (res, req)
Given mixture of req or res, how do i find which one is actually request and which one is response.
req is an IncomingMessage object and res is a ServerResponse object.
So check for unique properties on each, for example if the particular object has a writeHead() function, then it's the response object.
You may also be able to use instanceof to check: res instanceof http.ServerResponse.
Functions in JavaScript are not programmatically prototyped by parameter names. The length property of a function only provides the number of parameters specified in the definition:
var fn = function (one,two,three) { return "x"; };
console.log(fn.length); // 3
Although there are ways to retrieve these names (see this question), usually procedures simply ignore how you name the parameters of your functions/closures, and instead assume that you are following the proposed API.
For this reason, it remains as the best practice to pay attention to the API and name parameters accordingly. In a Node.js HTTP request listener, the request comes always before the response (it is documented and many examples are available). As mentioned by other answers, you can dynamically check whether the request is an http.IncomingMessage or whether the response is an http.ServerResponse, but it seems to me that you can avoid introducing an overhead just with proper naming.
With that said, given the variables req and res, it is easy to make a check at the top of a function body, like the code below. However, do note that this would only be remedying what can be prevented by just following the API contracts, and as thus I cannot recommend it (unless you really want to make functions with a more flexible API).
function(res,req) {
if (req instanceof http.ServerResponse) {
// wrong order, swap.
var t = req;
req = res;
res = t;
}
// handle request
}
If I assigned the res (result) object to a module level property, will it be unique for each request, or could a secondary request that is started before the callback finishes overwrite it?
var moduleData = {};
router.route('/publishers/:id')
.get(function(req, res) {
var id = req.params.id;
// Assigning the res property to a module level property called `moduleData`
moduleData.res = res;
db.findById('publishers', id, function(error, publishers) {
someFurtherWork(publishers); // would rather not pass the res object around
});
});
function someFurtherWork(publishers) {
someWork(publishers, function(error, data) {
// NOW we send the data back to user... is `res` guranteed to be the same one that initiated the request?
moduleData.res.send(data);
});
}
The router is itself event driven, meaning that each .get() request is handled as a callback to the server, when the thread is available. This guarantees each response object is unique to the function. Will a module level property be overwritten by a second GET request here?
If so, what workarounds are there, because I don't want to pass around my response object to multiple chained callback functions, that don't use them until all the data is collected.
There's a good reason I'm doing this, because if I have a bunch of callbacks, and once they're all done, then I need my response object. I figured if I used the response as a module level property, it won't need to be passed around.
The unique scope of each request your app receives is the same as the scope of the first callback you provide to the router, any variable that is defined in the outer scope is global to all requests.
You have to move the declaration of your var ModuleData = {} to the top of the callback. And because you defined someFurtherWork(publishers) function inside the same callback then it will have access via the closure to ModuleData object and you can just use it.
And if what you only need is to have the res object available to your nested callback and function so you can just use it as long as they all have a common root scope which is the initial callback function. Aren't closures awesome!