Cannot get query param in nodejs - node.js

I have this proxy-middleware application. It is not including express.js.
Server.js contains this:
const app = require('connect')(),
http = require('http'),
While the middlewares a set of rules, for example:
const httpProxy = require('http-proxy'),
HttpProxyRules = require('http-proxy-rules'),
const proxyRules = new HttpProxyRules({
rules: {
'/api/v1/stuff/([0-9]+)/documents/': 'http://0.0.0.0:3000/$1',
},
default: 'http://localhost:4443'
});
So all the other microservices are being intercepted by this proxy.
There is an "app.use" where a few checks are made.
Here I can see the request-object. Im interested in reading the query parameter attached to the url.
So when I have this:
http://localhost:8081/api/v1.1/stuff/63/documents/file.pdf?token=mytoken
Printing this:
console.log('GATEWAY',req.originalUrl);
Will output this:
http://localhost:8081/api/v1.1/stuff/63/documents/file.pdf?token=mytoken
However, how can I access the query parameter? As Im not using express, doing "req.query" gives undefined.
I have tried a bunch of solutions: "querystring", "url" etc. But they give very strange result and it is not easy to get the field itself. I can never do something like:
req.query
I had a look at connect documentation but there is nothing about getting the request query parameters.
What should I use?

Please check if you used the followings:
If not, please add them:
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
And try to get req.params

Related

How do I access URL parameter after i've routed my express app to another file?

My main express server is called app.js in Node.js.
app.use("/login", require(./routes/login));
app.use("/:id", require("./routes/users"));
When I try to access the URL parameter, it returns undefined.
I tried logging req.params:
const express = require('express');
const router = express.Router();
router.get('/dashboard', (req, res) => {
res.send(`Current Ornament Status and Data for ${req.params}`);
});
module.exports = router;
It gives me an empty array.
I suppose that it the parameter is inaccessible in another file after routing. Could you suggest a workaround?
I think you're missing some fundamental bits about express.js routing for this to make sense.
The requires line means it is loading another piece of code. So you need to show us that too.
The :id thing requires a longer explanation.
Let's say I want the server to process the URL /finduser/23
Where 23 can vary, could be just about any number. I am NOT going to write 99 different versions of router.get, right?
router.get("/finduser/1",...
router.get("/finduser/2",...
router.get("/finduser/3",...
No, what we do is turn that into a parameter
router.get("/finduser/:id",...
Then whatever number we pass turns into req.params.id, assume router passes req,res
EX: If we pass URL /finderuser/15, then req.params.id = 15
If you just pass /finduser then req.params.id gets NOTHING.
Full details are available here
http://expressjs.com/en/guide/routing.html#route-parameters
Your example:
router.get('/dashboard', (req, res)
Doesn't have ANY parameters. so req.params.id has nothing.

JSONSerialization makes incorrect JSON object. Swift

I'm creating an iOS app that connects to a NodeJS server. The get method works fine but the POST method has problems.
var urlRequest = URLRequest(url: "http://localhost:3000/register")
urlRequest.httpMethod = "POST"
let info: [String:Any] = ["username": "username", "password":"username", "email":"username#username.com"]
do {
let jsonInfo = try
JSONSerialization.data(withJSONObject: info, options[])
urlRequest.httpBody = jsonInfo
} catch {
print("ERROR")
return
}
The request gets sent but something goes wrong with JSONSerialization because this is the JSON data that the server gets:
{'{"email":"username#username.com","username":"username","password":"username"}': '' }
This is what I'm going for:
{"email":"username#username.com","username":"username","password":"username"}
This is part of the server code:
const express = require('express');
const bodyParser = require('body-parser');
var app = express();
var allowMethods = function(req, res, next) {
res.header('Access-Control-Allow-Methods', 'GET, POST, PATCH, PUT, DELETE');
next();
}
http.createServer(app).listen(3001);
console.log("Server started");
app.use(bodyParser.urlencoded({extended: true}));
app.use(allowMethods);
const _ = require('lodash');
let b = _.pick(req.body, ['username', 'password', 'email']);
Any ideas on what I'm doing wrong? I'd like to avoid using alamofire if possible. I've tried changing the format of the dictionary but always turns out as:
{ 'the whole dictionary is the key': ''}
I've also tried using pretty print and this was the result:
{ '{\n "email" : "username#username.com",\n "username" : "username",\n "password" : "username"\n}': '' }
Any help is appreciated. Thank you!
EDIT:
I tried Mike Taverne's suggestions.
I changed the server code to use this instead:
app.use(bodyParser.json());
But I receive an empty body from the simulator.
I also added these to the swift code:
urlRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
urlRequest.addValue("application/json", forHTTPHeaderField: "Accept")
But the server also receives an empty body and by empty body I mean the data I'm trying to send is received as empty by the server. When I check the httpBody the data is there but for some reason the server doesn't receive it.
I believe your Swift code is fine. When I did this in a playground:
print(String(data: urlRequest.httpBody!, encoding: String.Encoding.utf8)!)
It printed:
{"username":"username","password":"username","email":"username#username.com"}
I'm not an expert on body-parser, but I think that instead of this:
bodyParser.urlencoded({extended: true})
You should be using this:
bodyParser.json([options]) //not sure which options exactly you need
You may need to set Content-Type: application/json header as well. Refer to the body-parser documentation for more info.
I solved it by changing the data itself. Instead of forcing it to pass JSON I passed it as a string encoded using UTF8
let dataString = "username=username&password=username&email=username#username.com"
urlRequest.httpBody = dataString.data(using: .utf8)
I got the answer by using the method in this post:
HTTP Request in Swift with POST method

Define koa-router nested routes w/ prefixes

I'm trying to define different routes using koa-router and I'm having a hellova time getting it working.
Something like this:
const apiRouter = new KoaRouter({
prefix: '/api'
})
.use(bodyParser)
.post('/sign-in', signinMiddleware)
.get('auth-check', authCheckMiddleware)
const protectedApisRouter = new KoaRouter()
.use(authorizeMiddleware)
.get('/widgets', getWidgetsListMiddleware)
.post('/widgets', createWidgetMiddleware)
.get('/widgets/:widgetId', getWidgetByIdMiddleware)
.patch('/widgets/:widgetId', updateWidgetMiddleware)
apiRouter.use(
prodectedApisRouter.routes(),
prodectedApisRouter.allowedMethods()
)
koaApp.use(apiRouter.routes())
koaApp.use(apiRouter.allowedMethods())
I would expect that an requests to /api/widgets/* SHOULD enter into their respective middleware, after the bodyParser and authorizeMiddleware middleware` run, based on the documentation here: https://github.com/alexmingoia/koa-router#nested-routers
But instead, I'm getting 404's for all of those routes. What am I doing wrong?
Apparently the above code works just fine.. but in my authorizeMiddleware I was doing await next instead of await next() 🤦
Too bad there isn't a way to delete questions on here.. people are now gonna come here for issues not related to my idiocy.

Error: request entity too large in graphql services of node

I am working on node based graphql project, trying to send base64 format image to server.
I am using bodyparser module and configured it as bellow.
app.use(bodyparser.text({type: 'application/graphql'}));
app.use(bodyparser.json({limit: '50mb'}));
app.use(bodyparser.urlencoded({limit: '50mb', extended: true}));
I am able to send base64 images by direct node services but when it come to graphql services, it is throwing error as:
Error: request entity too large
For the sake of helping others who are using graphql-yoga npm package. The syntax to add bodyparser option is quite different and I took hours debugging & trying to make it work so adding the code here for reference :
const { GraphQLServer } = require("graphql-yoga");
const server = new GraphQLServer({
schema, //Your schema
context, //Your context
});
const options = {
port: 1234
bodyParserOptions: { limit: "10mb", type: "application/json" },
};
server.start(options, () =>
console.log(
"Server is running\m/"
)
);
Are you using the graphql-express npm package?
If so then the issue is likely this line:
https://github.com/graphql/express-graphql/blob/master/src/parseBody.js#L112
As you can see this sets a max size of 100kb for the request.
We ran into the same issue and fixed it by forking the repository and manually increased the max request size.
This might be a nice opportunity to contribute to the package though!
It would be nice if the limit were configurable.
For me, I specified the uploads and it worked:
const options = {
uploads: {
maxFieldSize: 1000000000,
maxFileSize: 1000000000
}
}
bodyParser only works with req.body and in your case you're handling multipart form

Node.JS GET / Parameters

For exemple this is my server with a simple API :
var express = require('express');
var rzServer = express();
rzServer.use(bodyParser.urlencoded({extended:true}));
rzServer.use(bodyParser.json());
app.get('/url', function(req, res) {
console.log(req.query.data); // String
console.log(JSON.parse(req.query.date)); // Object
});
req.query.data is interpreted as a string but it's a JSON Object.
Is it possible with the body-parser package to parse the querystring ?
Thanks.
body-parser is a middleware to parse body (it's its name). If you want to parse the query string, so you need another middleware for that.
Another thing : GET requests normally don't take any JSON parameters (no body). If you need to send a true JSON, perhaps you're not using the good HTTP method. Try to use a POST request, or create a true query string (http://expressjs.com/fr/api.html#req.query).

Resources