Separating express queries from routes - javascript

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")
})

Related

pino logger and express attach custom property to all logs

First up, node is not my thing. Nevertheless I find myself trying to figure out how to combine pino/pino-http and express to deliver some formatted logs. This part I have achieved.
What I was attempting to figure out for a short while was how to pass express via app.use(logger) a logger object that has got some base properties injected into it.
I tried a bunch of stuff, including creating a child logger and passing that to pinoHTTP() but although that did not error, i'd end up getting very long log objects which seemed full of goop and undesirable content.
pseudo code
const express = require('express');
const pino = require('pino');
const log = pino({level: process.env.LOG_LEVEL || 'info'});
const childLogger = log.child({'exampleProp': 'example-value'});
const logger = require('pino-http')({
logger: childLogger
});
const app = express();
const port = 3000;
app.use(logger);
app.get('/', (req, res) => {
logger.info('Hello World');
res.send('Hello World!');
});
app.listen(port, () => {
console.log('Example app listening on port ${port}')
});

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
}

express API extract data from URL

My api recives every 45 minutes a request:
GET http://MyHost/mediciones/sigfox_libelium/{device}/{data}/{time}/{customData#trama}
I want my code to save {device}, {data}, {time} and {customData#trama} into different variables so I can parse it into readable values(all data it is send hexadecimal) and insert them into my database.
How do I take those values out of the URL?
Also, what is the purpose of req, res? I guess It stands for request, respond.Respond sends back to the client but, request? I dont really understand how it works. Im learning all this new, hope someone can help.
This is my API code, I tried it with postman and it works fine so far:
const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const Pool = require("pg").Pool;
const pool = new Pool({
user: "mgr#stanpgtest",
host: "stanpgtest.postgres.database.azure.com",
database: "my db name",
password: "my pass",
port: 5432
});
const app = express();
app.use(cors());
app.use(bodyParser.json());
app.listen(8000, () => {
console.log(`Server is running, listening to port 8000`);
});
app.post("mediciones/sigfox_libelium/{device}/{data}/{time}/{customData#trama}", (req, res) => {
const { label, status, priority } = req.body;
pool.query(
"select now()",
(error, results) => {
if (error) {
throw error;
}
res.send(results);
}
);
});
You need to write the path in this format, then extract your params from req.params.
app.post("mediciones/sigfox_libelium/:device/:data/:time/:customData", (req, res) => {
const {device, data, time, customData} = req.params
}
I'm not sure what #trama is meant to be, but I guess you can't use # in the route pattern.

express parameters and api endpoint

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);
});

Dynamically change Express routes on CMS update

I have a project using NextJS, with Express for server side routing.
lib/routes/getPages
const routes = require('next-routes')();
const getEntries = require('../helpers/getEntries');
module.exports = async (app) => {
const { items: [globalSetings] } = await getEntries({
content_type: 'xxxxxxxx',
include: 1,
limit: 1,
});
routes
.add('/', 'index')
.add(`/${globalSettings.fields.blogSlug}/:slug`, 'blog');
return routes.getRequestHandler(app);
};
server.js
const express = require('express');
const next = require('next');
const getPages = require('./lib/routes/getPages');
const app = next();
app.prepare().then(async () => {
const server = express();
const pageRoutes = await getPages(app);
server.use(pageRoutes);
server.listen(3000);
});
I get slugs for routes (such as the blog section) from my CMS API (which is Contentful in this case). I am wondering how I handle an admin changing a slug in the CMS when the app is already running?
Guessing I will need to restart the app for the new slug/route to work. In this case, will I need to use a webhook and listen for changes from the CMS then somehow restart the app programmatically? This could work but might add overhead. Is there a better way to do it?
You can use a workaround in order to do dynamic routes in express. Here's what I'm using in my Typescript app:
// https://github.com/expressjs/express/issues/2596
let dynamicRouter: express.Router
app.use(
(req, res, next) => dynamicRouter(req, res, next),
)
function loadMyRoutes() {
const newRouter = express.Router()
const newMiddleware = // load my new middleware
newRouter.use(newMiddleware)
dynamicRouter = newRouter
}
You can then call loadMyRoutes() in response to a Contentful webhook.
app.post(`/webhook`, () => {
loadMyRoutes()
})

Categories

Resources