I wanted to save authUser object into fastify request before it comes into handler.
I did it like this in router.
fastify.route({
method: 'GET',
url: '/user',
preHandler: [
checkValidRequest,
checkValidUser
],
handler: controllers.getAllUsers
})
But It always comes into handler before it's getting it from db. so, that means I can't run async function into middleware in fastify?
As documented:
It is important to not mix callbacks and async/Promise, otherwise the hook chain will be executed twice.
And it is your case
Related
Trying to keep my code organized. I have a controller directory and router directory. The goal is to make an api call and retrieve data.
CONTROLLER
function searchName(req, res) {
res.setHeader("user-key", process.env.APIKEY)
res.redirect(`https://api-endpoint.igdb.com/games/?search=${req.params.game}&fields=*`)
}
ROUTER
router.get('/search/:game', Controller.searchName)
I export router, and require it in my server.js file. In POSTMAN, this works fine; I do have my API Key hard coded in Postman. I've tried many different methods but can't seem to pass the header with my ApiKey when making the initial request in the code. Additionally, being new to nodejs, I'm not sure if the request redirect is sufficient in this scenario. Ultimately, setHeader is not working
It sounds like you're trying to make an async call to another service, pull back some data, and send that back to the client that called your service. In a nodejs application it's quite trivial to make a new HTTP request. Nodejs has a built in HTTP.Agent, but I'd suggest trying out the axios library as it makes it even easily. This will result in something like this:
const axios = require('axios');
function searchGame(req, res) {
const requestOptions = {
method: 'GET',
uri: `https://api-endpoint.igdb.com/games/?search=${req.params.game}&fields=*`,
headers: {
"user-key": process.env.API_KEY
}
}
axios.get(requestOptions)
.then(function (response) {
// This is the data the remote service gave back
res.send(response.data);
})
.catch(function (error) {
// The remote gave an error, lets just forward that for now
res.send({error: error});
});
}
Here we build an axios request from the req object, we make the request using axios.get, we then wait for the "promise" (this is an async javascript concept if you've not come across it before), then we take the response from that and forward it back as the res. Lets pretend for argument sake that this is a JSON response, but it could be anything.
I am fairly new to Node-Express. I am using the Express Router for routing the request. What I am basically doing is a video view, then delete function.
This is my code.
router.get('/videodelete', function(req, res) {
// Some synchronous operation using sync-exec
res.writeHead(200, {
"Content-Type": "text/html"
});
res.end('<video src="../video/video.mp4" controls></video>');
// response is sent. Now delete the file after the response is shown.
fs.unlink("../video/video.mp4");
})
I also tried fs.unlinkSync. In all these cases, the delete operation is happening before sending the response. I wish to trigger the delete operation only after sending response. Is there any way to perform this action only after sending the response?
NodeJS is retrying the backend API calls if it wont get any reponse within its default timeout(2mins). This is causing an Issue for POST/PUT/DELETE API calls, which are taking more reponse time(> 2mins). Request is going to backend multiple times from Nodejs, for one request from user.
I dont want to Increase the default timeout, as my response can vary everytime.
Please let me know if there is any configuration in nodeJs/expressJS, so that i can stop the nodeJS retry totally or customise configuration for only POST/PUT/DELETE API.
Example of how i send my request:
let express = require('express');
let router = express.Router();
let async = require('async');
let expressListRoutes = require('express-list-routes');
async.parallel([
function () {
//url: resource/add/
router.post('/add', function (req, res) {
let uiModel = req.body;
let outputJson = Parser.parse(uiModel, 'CREATE');
let requestPromiseModel = {
uri: `${RESOURCES}/${uiModel.resourcePluginId}`,
method: HttpMethod.POST,
json: true,
body: outputJson,
headers: {
'Accept': MIMETypes.APPLICATION_JSON,
'Authorization': MIMETypes.TOKEN_TYPE + req.token
},
resolveWithFullResponse: true
};
rp(requestPromiseModel).then(function (results) {
res.send(results);
}).catch(function (err) {
log.error(`Error: Create Resource Action: ${err}`);
res.send(err.response);
});
});
}
]);
expressListRoutes({prefix: '/resource'}, "API:", router);
module.exports = router;
Thanks for the help In Advance :)
The usage of async.parallel in your code is useless. You are running only one function with it so it doesn't make much sense to run one thing in parallel. Also that function doesn't call the callback provided by async.parallel as its first argument so async.parallel thinks it never finishes. And to make things worse all you do in that function is call router.post() which could be called directly as:
router.post(
// ...
);
instead of:
async.parallel([
function () {
router.post(
// ...
);
}
]);
as you do know.
The only thing that it does is that it can potentially call the expressListRoutes({prefix: '/resource'}, "API:", router); before the router.post() gets called.
Also you are using req.body without using body-parser.
And finally, here is a way to define the timeout for request and request-promise - see the docs:
https://github.com/request/request#requestoptions-callback
timeout - Integer containing the number of milliseconds to wait for a server to send response headers (and start the response body) before aborting the request. Note that if the underlying TCP connection cannot be established, the OS-wide TCP connection timeout will overrule the timeout option (the default in Linux can be anywhere from 20-120 seconds).
Make sure that your OS timeouts are not taking precedence here.
I am newbie in adonisjs.
I want to implement custom response if route method not match.
I have route like this
Route.post('/create', function * (request, response) {response.send('success')})
when call url /create with GET in browser, It send respond 404 not found. Can I use custom response with 405 method not allowed?
The Adonisjs not use request and response like expressjs, you need deconstruct the object.
Your route will running with that code:
Route.post('/create', ({ request, response }) => {
response.send('success')
})
or
Route.post('/create', (ctx) => {
ctx.response.send('success')
})
I just found out the simplest method.
Just put this at the bottom of all the routes
Route.get('*', ({ view }) => view.render('errorPage'))
It will check all the routes from the top, reaches the bottom and hits the view
How can I mock a client and a server in Mocha using NodeJs.
Specifically, I have the following code:
app.post ('path name', function (req, res) {
// Some Action
res.send(response);
});
I want to mock the req, res parameters and test res (status, header, message).
Mocha itself doesn't provide mock/stub/spy type functionality. Sinon is a popular library that does. The home page includes examples of testing ajax as well as their Fake XMLHTTPRequest object.
I found Node-Fakeweb useful
var request = require('request');
// Mocking a client request
request.get({ uri: 'URI', body: 'body' }, function (err, resp, body) {
// Some Action
});
});
You can use mocha with supertest to mock a request. Here is a wonderful tutorial about how to do it:
http://thewayofcode.wordpress.com/2013/04/21/how-to-build-and-test-rest-api-with-nodejs-express-mocha/