how to pass query parameter "as is" in nestjs? - nestjs

I have a nestJS gateway, and I need it to proxy a request from my front end to an external API.
I am passing a list of query parameters from the FE.
fe : localhost:3333/autocomplete/prediction?test=2&toto=2
I want my nestJs app to just get the query parameters and send them untouched :
#Get('proxy')
async proxy(#Query() query) {
await this.httpService
.post(`${endpoint}/?${query}`)
}
problemn is, #Query() query return an object and I don't want to reprocess the parameters , and #Req() req: Request doesn't have a simple way to get the string
I just want a good way to retrieve the test=2&toto=2
edit : yes there is req.url.split('?')[1] but isn't there something built in ?

I believe req.search (from http.IncomingMessage) is the way.

Related

how to get records from mongodb through node js

Here In my mongo collection I have few records. I am writing an API in node js where I pass the ID in request body. My API have to take ID from request body and need to fetch it's whole records in response. but I am getting empty array.
My mongo collection record:
[{ accountId:"a1",name:"test"}]
My Node js code approach:
exports.getById = async (req) =>{
let id = `"` + req.body.accountId +`"`;
let accountId = await db.collection('account-details').find({id}).toArray();
return accountId
}
In request body, I am passing accountId as :
{
"accountId":"a1"
}
The ID is in the form of string. When I am trying to fetch whole records with the provided ID through my API, I am getting response as []. Can anyone please help me on this
You cannot send a body with an HTTP GET, therefore it will not be available in the req object, so req.body.accountId will be undefined and id will be an empty string.
You need to use POST (or PUT) to send body data.
But the more usual solution in your situation is to use GET with dynamic routing, where you add the id to the route e.g.: http://example.com/api/accounts/1234
If you use Express, in your router you need to add the route api/accounts/:id to your router. The id will be available in your code as req.params.id.
See Express docs. For other frameworks this will be something alike.
Hope this helps.

How can I route a path which has '?' character in it in nestjs?

For example in browser we send /controller/test?value=2 but I want to route this at an endpoint? I have another endpoint /controller/test which captures even the requests made to this route
That's a query string.
You can use #Query decorator in the function parameter
#Get('/path')
async find(#Query() query) {
console.log(query);
}
More info
In this situation, it seems like your route /controller/test accepts a query parameter value. Regardless of whether or not you query that route with the query parameter value, all requests will hit your route controller at controller/test.
In other words, your server treats
GET /controller/test as a request to /controller/test as a request with value: undefined
and
GET /controller/test?value=2 as a request to /controller/test as a request with value: 2
Therefore, your controller should look something like (assuming you're using typescript)
interface ControllerQuery {
value?: number
}
#Get('/controller/path')
async controller( #Query query: ControllerQuery ) {
if (query.value) {
console.log(query.value);
} else {
console.log('No value provided, now what?');
}
}
Like said above, query params are not filtered by route. But you could do something like this, which would be more restful as well. That or having a search endpoint.
#Get('/path')
async without() {
console.log('without param');
}
#Get('/path/:value')
async find(#Param('value') value: string,) {
console.log(value);
}
#Get('/path/search')
async search(#Query() query) {
console.log(query);
}

What to do when NodeJS rest api is sendind status 404 while using parameters?

I am having a strange problem while writing my api. I am using Nodejs and express. The problem occurs when i try to use GET with parameters.
This is my routes code
router.get('/addFriends/:email', (req, res, next) =>{
const email = req.params.email;
UserSchema.find({email: email}, { "friendsPending.emailSender": 1, _id : 0}, (err, data) =>{
if(err){
res.status(404).send(err);
}else{
res.status(200).send(data[0]);
}
});
});
This is my call in Postman : /users/addFriends?email=a
When running this call, server returns 404 status. It happened even when i tested it with another get call.Any comments are appriciated, however other POST and GET calls work normally (they use body not parameters). Thanks
You mixed query params and url params. To make your example working, you need to use /addFriends/my-email#gmail.com instead of /users/addFriends?email=a.
If you need to send emails via query params (everything after ?) use req.query in your controller instead of req.params.email.
This route definition:
router.get('/addFriends/:email', ...);
expects a URL that looks like this:
/addFriends/someEmail
And, you would use req.params.email to refer to the "someEmail" value in the URL path.
Not what you are trying to use:
/addFriends?email=a
If you want to use a URL such as (a URL with a query parameter):
/addFriends?email=a
Then, you would have a route definition like this:
router.get('/addFriends', ...);
And, then you would refer to req.query.email in the route handler. Query parameters (things after the ? in the URL) come from the req.query object.
In Express, route definitions match the path of the URL, not the query parameters.
when you use /addFriends/:param you force the router to match any request tha have a part in path as :param.For example:
/users/addFriends/toFavorates // will **match**
/users/addFriends/toFavorates?email=a // will **match**
/users/addFriends?email=a // will **not** match
if you want to make :param as optional part of url path put a ? after it
/addFriends/:param?
it will tell express route that :param is an optinal part. See this question
express uses path-to-regexp for matching the route paths. read the documentation for more options

How can I put an Express REST layer on top of an Apollo GraphQL server?

I'm looking into putting a REST layer (using Express) on top of a GraphQL server (Apollo Server v2) to support some legacy apps. To share as much logic as possible, the REST endpoint should ideally wrap a GraphQL query that I'm sending to the GraphQL server, and be able to do small modifications to the response before sending the response to the client.
I'm having trouble figuring out the best way to query the apollo server from the Express routing middleware. So far I've explored two different solutions:
Modify the request from the REST endpoint such that req.body is a valid graphql query, change the req.url to /graphql, and call next(). The problem with this is that I cannot modify the result before it's being sent to the client, which I need to do.
Calling the /graphql endpoint with axios from the routing middleware, and modify the response before sending to the client. This works, but feels to me a bit hacky.
Do you have other suggestions, or maybe even an example?
I believe the solution 2 is okay to implement.
I've made a similar implementation, but in my case, a GraphQL service fetches data from another(multiple) GraphQL service(s).
And somewhere down the line I did something like this:
export type serviceConnectionType = {
endpoint: string
queryType: {
query: Object // gql Object Query
variables: {
input: Object // query arguments (can be null)
}
}
}
export async function connectService(params: serviceConnectionType) {
const response = await fetch(params.endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(params.queryType),
})
if (response.status === 404) {
console.warn('404 not found')
}
return response.json()
}

Azure Functions: Get full request URL including query string in a HTTP Trigger function

Is there a way to get the full request URL, including the query string part, inside a Azure Functions HTTP Trigger Javascript function?
The req (and context.req) parameters do include the url without the query string in req.url, and the query string as key-value pairs inside req.query. But as far as I can see, it's not possible to directly access the full request url. It's also impossible to reconstruct the full URL with only the base url and the key-value object.
For example something like http://foo.azurewebsites.net/api/bar/baz?a=1&&&b=2&c=&d===5&e=&f=6&g
gets turned into
{
url: '/bar/baz/',
query: {
a: '1',
b: '2',
c: '\n\u0001d\u0012\u0003==5',
e: '\n\u0001f\u0012\u00016',
g: '\n\u0001a\u0012\u0003\n\u00011'
}
}
Having access to the full request URL is required for building a proxy, a URL shortener etc. And since there is no official format for query strings, only conventions, it'd be nice to be able to handle all types of query strings just in case.
Based on docs, you should be able to get it from req.originalUrl:
module.exports = function (context, req) {
context.log('HTTP trigger function processed a request: ' + req.originalUrl);
context.done();
};
UPDATE from comments: apparently, this doesn't work on 2.0 runtime yet, but will eventually be supported: issue.

Resources