Extract the common query path from RESTFUL URL (Ablate the resources) JS - javascript

I have a RESTFUL url design like this: GET /street/:streetName/house/:houseNumber or GET /street/:streetName/house/listings. As you can see, the :streetName and :houseNumber are resource names. I am trying to extract the static (common) parts from the url for some following logics which means I want to get /street/house and /street/house/listings (ablate all resources parts in the url).
I was trying to find a JS lib for this but didn't find one. Any pointers?
PS: I can do some string matching to achieve this like split by "/" then concat them and only care about the key words, so I can ignore all resource names. But this doesn't seem robust.

Assuming you have a route for each URL pattern, you can set an additional property req.staticParts in each middleware:
app.get("/street/:streetName/house/:houseNumber", function(req, res, next) {
req.staticParts = "/street/house";
...
})
...
.get("/street/:streetName/house/:houseNumber/listings", function(req, res, next) {
req.staticParts = "/street/house/listings";
...
})
.use(function(req, res) {
additionalLogic(req.staticParts);
});
This avoids string operations and is very explicit, therefore very robust.
Parsing the URL into staticParts without knowledge of the routes is problematic. For example, parsing the URL /street/house/25 based on keywords would lead to req.staticParts = "/street/house", but there is no matching route for it.

Related

Object of which I have a working method for is somehow undefined? Javascript app.patch request [duplicate]

I am trying to create two routes in my express app. One route, without a parameter will give me a list of choices, the other one with a parameter will give me the choice related to the id.
router.get('/api/choice', choice_controller.get_choices);
router.get('/api/choice/:id', choice_controller.get_choice);
When I go to .../api/choice/?id=1 the api returns the list of choices, and therefore follows the route without the param (/api/choice). How do I make sure that the router does not omit the parameter?
Thanks in advance.
UPDATE
It seems that it does not fire the /api/choice/:id route. If I remove the one without the param, it gives a 404 so. Could someone explain to me why /api/choice/?id=1 is not getting picked up by /api/choice/:id?
Basically, your declared routes are documented in the Express documentation.
The second route is resolved by a URL like /api/choice/hello where 'hello' is mapped into the req object object as:
router.get('/api/choice/:id', function (req, res) {
console.log("choice id is " + req.params.id);
});
What you are actually trying is mapping query parameters.
A URL like /api/choice/?id=1 is resolved by the first router you provided.
Query parameters are easy to get mapped against the request as:
router.get('/api/choice', function (req, res) {
console.log('id: ' + req.query.id);
//get the whole query as!
const queryStuff = JSON.stringify(req.query);
console.log(queryStuff)
});

Steam API Request Failed [duplicate]

I am trying to create two routes in my express app. One route, without a parameter will give me a list of choices, the other one with a parameter will give me the choice related to the id.
router.get('/api/choice', choice_controller.get_choices);
router.get('/api/choice/:id', choice_controller.get_choice);
When I go to .../api/choice/?id=1 the api returns the list of choices, and therefore follows the route without the param (/api/choice). How do I make sure that the router does not omit the parameter?
Thanks in advance.
UPDATE
It seems that it does not fire the /api/choice/:id route. If I remove the one without the param, it gives a 404 so. Could someone explain to me why /api/choice/?id=1 is not getting picked up by /api/choice/:id?
Basically, your declared routes are documented in the Express documentation.
The second route is resolved by a URL like /api/choice/hello where 'hello' is mapped into the req object object as:
router.get('/api/choice/:id', function (req, res) {
console.log("choice id is " + req.params.id);
});
What you are actually trying is mapping query parameters.
A URL like /api/choice/?id=1 is resolved by the first router you provided.
Query parameters are easy to get mapped against the request as:
router.get('/api/choice', function (req, res) {
console.log('id: ' + req.query.id);
//get the whole query as!
const queryStuff = JSON.stringify(req.query);
console.log(queryStuff)
});

Two page templates that both render dynamically but share the same route

I have two custom page types that use dynamic routing, queried from Prismic CMS, service_page and about_page. I'm running into a problem in my express server custom routing however - if my servicePage route is listed first, the aboutPage wont render. But if its vice versa, the servicePage won't route but my aboutPages will. Is there a way to have two custom types with dynamic routes? I understand I can add a prefix to them (services/:uid or about/:uid) but I'd really rather avoid that for company purposes.
server.get('/:uid', (req, res) => {
const nextJsPage = '/servicePage';
const queryParams = { uid: req.params.uid };
app.render(req, res, nextJsPage, queryParams);
});
server.get('/:uid', (req, res) => {
const nextJsPage = '/aboutPage';
const queryParams = { uid: req.params.uid };
app.render(req, res, nextJsPage, queryParams);
});
What is your purpose?
When using routing in general the first listed url that matches the url you requested will be displayed. You can't expect any other behavior.
I don't think you can use Regex here if there is a difference between the ids (such as 9 digits vs. 2 digits for example), but you can try searching about it. Otherwise, you must use a prefix.

how to pass a url as a "url parameter" in express?

In my express app I have a router listening to api/shorten/:
router.get('api/shorten/:longUrl', function(req, res, next) {
console.log(req.params.longUrl);
}
When I use something like:
http://localhost:3000/api/shorten/www.udemy.com
I get www.udemy.com which is what I expect.
But when I use:
http://localhost:3000/api/shorten/http://www.udemy.com
I get a 404 error.
I want to get http://www.udemy.com when I access req.params.parameter.
I'm not sure if you're still looking for a solution to this problem. Perhaps just in case someone else is trying to figure out the same thing, this is a simple solution to your problem:
app.get('/new/*', function(req, res) {
// Grab params that are attached on the end of the /new/ route
var url = req.params[0];
This way you don't have to sweat about any forward slashes being mistaken for routes or directories, it will grab everything after /new/.
You need to use encodeURIComponent in the client, and decodeURIComponent in the express server, this will encode all the not allowed characters from the url parameter like : and /
You need to escape as so:
escape("http://www.google.com")
Which returns:
"http%3A//www.google.com"
I just want to add that if you pass another params like ?param=some_param into your "url paramter" it will not show up in req.params[0].
Instead you can just use req.url property.

How to use parameters containing a slash character?

My MongoDB keys in person collection are like this:
TWITTER/12345678
GOOGLE/34567890
TWITTER/45678901
...
I define getPersonByKey route this way:
router.route('/getPersonByKey/:providerKey/:personKey').
get(function(req, res) { // get person by key
var key = req.params.providerKey + '/' + req.params.personKey;
// ...
}
);
Of course I'd prefer to be able to write something like this:
router.route('/getPersonByKey/:key').
get(function(req, res) { // get person by key
var key = req.params.key;
// ...
}
);
But this doesn't work, since GET http://localhost/getPersonByKey/TWITTER/12345678 of course results in a 404, since the parameter with the slash is interpreted as two distinct parameters...
Any idea?
Express internally uses path-to-regexp to do path matching.
As explained in the documentation, you can use a "Custom Match Parameter" by adding a regular expression wrapped in parenthesis after the parameter itself.
You can use the following path to get the result you need:
router.route('/getPersonByKey/:key([^/]+/[^/]+)').
get(function(req, res) { // get person by key
var key = req.params.key;
// ...
}
);
You can test and validate this or any other route here.
You can use this if your parameters has containing slashes in it
app.get('/getPersonByKey/:key(*)', function(req, res) { ... })
It works for me (at least in Express 4). In my case, I used parameters like ABC1/12345/6789(10).
Hopefully this useful.
app.get('/getPersonByKey/:key(*)', function(req, res) { ... })
This isn't working for me.
Swagger-ui will encode the path var before using it.
e.g. article/2159 will become article%2F2159.
When going directly with curl, it will not get encoded. the slash will remain a slash instead of %2F. And then the route is not matched.
Update: I'm on fastify. On express 4.X this works correctly.

Categories