express parameters and api endpoint - javascript

I have an express api endpoints for different purpose, but a single one is returning results for all the endpoints.
example.
api/:id returns id.
api/:id?region=east returns {region: "east"}
I know in the first case we use req.params, second case req.query.
My problem is for both calls, the results are from first case only.
How can I resolve this?
sample code app.js file
const express = require('express');
const app = express();
app.use(express.json());
app.use(express.urlencoded({extended:false}));
app.use('/api', require(./server/user.js));
const port = process.env.PORT || 3000;
app.listen(port, () => console.log(`Listening on port ${port} `));
#user.js file
const express = require('express');
const router = express.Router();
//endpoint api/10
//ie 10 is the id
router.get('/:id', (req,res) =>{
let id = req.params;
return res.json(id);
});
//note the second router should be using query string
//ie api/10?region=east
router.get('/:id', (req,res) =>{
let id = req.params;
return res.json(id);
});
My problem is the second api endpoint doesn't work. it executes the first api endpoint.
1 Updates above

You can use single route instead of making two different routes, you will just need to check for query string in the request as shown below.
router.get('/:id', (req,res) =>{
let id = req.params;
let region;
if(req.query){
region = req.query.region;
}
return res.json(id);
});

Related

using a subdomain as api in nodejs

I want to send a request to api as a subdomain like so :
https://api.example.com
So I have this in server js:
const express = require('express');
const app = express();
const subdomain = require('express-subdomain');
app.use(subdomain('api', require('./_helpers/api')));
In the api.js inside _helper folder I have this:
const express = require('express');
const router = express.Router();
router.post('/', fetch);
module.exports = router;
async function fetch(req, res) {
console.log('fetch api worked');
}
But the console.log('fetch api worked'); never reaches and never execute.
I want to execute the fetch function inside _helper/api.js . How can I do this?

Node Express dynamic route/path

How can I implement and get a dynamic route or path with Express package? The main problem is the path is an id pass by the client and had no control over it.
const express = require('express');
const dynamic_path= express();
dynamic_path.get('/user', (req, res) => {
});
exports.v1 = functions.runWith(runtimeOpts).https.onRequest(dynamic_path);
The above will result as https://my-app.net/v1/user and the client request will be https://my-app.net/v1/user/user_id. I need to allow dynamic path and I need to get the value of user_id as well for future usage.
Added :user_id to the route.
dynamic_path.get('/user/:user_id', (req, res) => {
const user_id = req.params.user_id;
});
Use the route:
https://my-app.net/v1/user/:user_id
Your code will be like this:
dynamic_path.get("/user/:user_id" , (req, res)=>{
let user_id = req.parmas.user_id
}

Separating express queries from routes

I'm trying to make an express route that basically allows me to input an equity name as a query by putting ?symbol= on the URL. After the equity name, I want to add a new route.
const express = require("express")
const app = express()
app.get("/api/v1/equity/latest", (req, res) => {
res.send(req.query)
})
app.listen (3000, () => {
console.log("listening to port 3000")
})
when I give then GET the URL as localhost:3000/api/v1/equity?symbol=BBNI/latest/ and then look at the queries received, it received as symbol = BBNI/latest/
How do I separate the symbol query from the next /latest route?
It's a weird URL pattern, because if any dev sees this url:
/v1/equity?symbol=BBNI/latest/
It is implied that the symbol parameter is indeed BBNI/latest/ and not just BBNI
However, if you want to 'separate' these parts, you can just do:
const [symbol, latest] = req.query.symbol.split('/', 2);
But you probably should design a better URL structure.
I think it's not a good method.
Please try this.
const express = require("express")
const app = express()
app.get("/api/v1/equity/:symbol/latest", (req, res) => {
res.send(req.params.symbol)
})
app.listen (3000, () => {
console.log("listening to port 3000")
})

get all registered route in nodejs [duplicate]

This question already has answers here:
How to get all registered routes in Express?
(31 answers)
Closed 2 years ago.
i want to return all registered route in my project.
i use this code for retur nall routes :
const app = require("express");
let routers = app._router.stack
.filter((r) => r.route)
.map((r) => {
return {
method: Object.keys(r.route.methods)[0].toUpperCase(),
path: r.route.path,
};
});
but it not worked and show me this error :
(node:13092) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'stack' of undefined
Edit :
my routes :
const express=require('express');
const router=express.Router();
const roleRouter=require('./role');
const userRouter=require('./user');
const managerRouter=require('./manager');
const accessRouter=require('./access');
const settingRouter=require('./setting');
router.use('/role',roleRouter);
router.use('/user',userRouter);
router.use('/manager',managerRouter);
router.use('/access',accessRouter);
router.use('/setting',settingRouter);
module.exports=router;
and use that in the main js file :
app.use(require("./routes/index"));
how can i return all routes in my projects ???
the app supposed to be created with express function
const express = require('express');
const app = express();
then you can get all of the registered routes, make sure to put this line after you register your app routes
console.log(app._router);
So the full code will look like this:
const express = require('express');
const app = express();
const port = 3000;
console.log(app._router); // undefined
app.get('/', (req, res) => res.send('Hello World!'))
console.log(app._router.stack); // showing routes
app.listen(port)
EDIT:
To return all of your routes from your API endpoint, you can do this (not sure why you want to do this though)
const express = require('express');
const app = express();
const port = 5000;
app.get('/', (req, res) => {
res.json(app._router.stack);
})
app.get('/example', (req, res) => {
// This route will also be listed when you call "/"
res.send();
})
app.listen(port)

Is it possible a single API handles multiple requests in Node JS?

My goal is to create an API that handles multiple requests. By doing this, I need to pass a string as an argument to the url of API like this:
// index.js in client
fetch(`http://localhost:4000/routerName/${tableName}`).then()
// router.js
router.get(`/${tableName_from_client_page}`, (req, res) => { // Do Something })
A problem is, the browser can't connect to the targeted pages unless I create a whole new APIs for every matching tableNames.
I want my API handles multiple requests by receiving the tableName as its /url.
Are there some tricks to solve this problem?
This is how my whole router looks like:
// Router
const express = require('express'),
db = require('./db.js'),
router = express.Router();
router.get('/table', (req, res) => {
db.loadTable('SELECT * FROM someTable', res);
}) // Handles only one request on the name of url; /table
router.get(`/${tableName_from_client_page}`, (req, res) => {
db.loadTable(`SELECT * FROM ${tableName_from_client_page}`, res)
}) // Handles multiple requests, depending on its argument.
module.exports = router;
// Router
const express = require('express'),
db = require('./db.js'),
router = express.Router();
router.get('/table', (req, res) => {
db.loadTable('SELECT * FROM someTable', res);
}) // Handles only one request on the name of url; /table
router.get('/tables/:tableName', (req, res) => {
db.loadTable(`SELECT * FROM ${req.params.tableName}`, res)
}) // Handles multiple requests, depending on its argument.
module.exports = router;
// Router
const express = require('express'),
db = require('./db.js'),
router = express.Router();
This API will only handle one request "/table".
router.get('/table', (req, res) => {
db.loadTable('SELECT * FROM someTable', res);
})
To handle multiple requests checkout below code
but make sure to write this API last in the route file, If you write this API before the "/table" API then your "/table" request will also be handled by this API.
router.get('/:table_name', (req, res) => {
db.loadTable(`SELECT * FROM ${req.params.table_name}`, res)
})
module.exports = router;

Categories

Resources