Given a simple Express app
const express = require('express')
const app = express()
app.get('/users/:userId', (req, res) => {
console.log(req.orginalUrl) // /users/1
console.log(req.route.path) // /users/:userId
res.json({})
})
It gives me the right and complete route schema req.route.path.
But if we use a router to abstract the first part of the URI then it doesn't give the full route schema anymore.
const express = require('express')
const app = express()
const users = express.Router()
.get(':userId', (req, res) => {
console.log(req.orginalUrl) // /users/1
console.log(req.route.path) // /:userId
res.json({})
})
app.use('/users', users)
It there a way to get /users/:userId while using routers?
You just have to concatenate baseUrl and path like this :
let fullPath = req.baseUrl + req.route.path;
Related
I'm building an API for my web app and I was able to successfully send requests to the routes in Post.js when they only had url params. But when I try to create a route like '/allposts' (the last endpoint in Post.js) , I receive a 404 error message on postman. Here's my code:
router.post('/', (req, res) => {
// Endpoint 1 code here
})
router.get('/:id', (req, res) => {
// Endpoint 2 code
})
// This is the route that I can't to send requests to
router.get('/ap', async(req, res) => {
try{
const ap = await P.find()
res.send(ap)
} catch(error){
log(error)
res.status(500).send("error")
}
})
server.js
const express = require('express')
var cors = require('cors')
const fs = require('fs');
const path = require('path');
var app = express()
app.use(express.static(path)
app.use(cors())
const bodyParser = require('body-parser')
app.use(bodyParser.json());
var p = require("./routes/P.js");
app.use('/post', p);
const PORT = process.env.PORT || 3001
app.listen(port, () => {
log(`Listening on port ${PORT}...`)
});
When I send a request to http://localhost:3001/post/ap, I'm getting the a 404 Not Found error, but the first two routes work fine. It seems like routes with url params work, but the allposts route does not. Any help would be greatly appreciated. Thanks.
Main problem is the order of the routes.
router.get('/:id') will be initialized before router.get('/allposts'). So when you want to access /allposts the first router will catch it.
You need to switch the init order.
First router.get('/allposts') then router.get('/:id').
I want to broke down my routers into separate file rather than keeping all API routes in a single file. So i tried to identify user URL using a middle ware and call the api according to the url as you seeing bellow but middleware function is not working . how to solve this?
//HERE IS INDEX.jS file CODE
const express = require("express");
const dotenv = require("dotenv");
const app = express();
const PORT = process.env.PORT || 7000;
app.listen(PORT);
app.use("/users", require("./routes/users/users"));
//==========================================================
//HERE IS users.js FILE CODE
const express = require("express");`enter code here`
const router = require("express").Router();
express().use(selectApi);
function selectApi(req, res, next) {
console.log("this line also not executing")
switch(req.originalUrl){
case '/':
// calling api here from a nother separate file
case '/user/:id'
// calling api here from a nother separate file
}
}
module.exports = router;
There is an example in the Express.js Routing Guide. I've modified it slightly to fit your example.
users.js
var express = require('express')
var router = express.Router()
// middleware that is specific to this router
router.use(function timeLog (req, res, next) {
console.log('Time: ', Date.now())
next()
})
// define the home page route
router.get('/', function (req, res) {
// calling api here from a nother separate file
})
router.get('/user/:id', function (req, res) {
// calling api here from a nother separate file
})
module.exports = router
index.js
const express = require("express");
const dotenv = require("dotenv");
const app = express();
const PORT = process.env.PORT || 7000;
app.listen(PORT);
app.use("/users", require("./routes/users/users"));
I'm new to express and node js, I recently learned how to write API for express but at the end, I get some sort of problem which not resolved by me after several tries. I could not get a response on localhost:8080/users
src/routes/users.js
const { Router } = require("express");
const router = Router();
const getUsers = (req, res) =>
res.send(Object.values(req.context.models.users));
const getUser = (req, res) =>
res.send(req.context.models.users[req.params.userId]);
router.get("/users/", getUsers);
router.get("/users/:userId", getUser);
module.exports = router;
src/routes/index.js
const user = require("./user");
const message = require("./message");
module.exports = {
user,
message
};
src/index.js
const express = require("express");
const app = express();
// Custom Modules
const routes = require("./routes");
const models = require("./models");
// Application-Level Middleware Starts
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use((req, res, next) => {
req.context = {
models,
me: models.users[1]
};
console.log(req.context.models.users);
next();
});
// Used Routes
app.use("/users", routes.user);
app.use("/messages", routes.message);
// App Listning to HTTPS Module
app.listen(process.env.PORT);
You need to fix your endpoints in users.js:
router.get("/", getUsers);
router.get("/:userId", getUser);
The reason is because of app.use("/users", routes.user); in your index.js, where the endpoint for users is set. If you leave /users/ in users.js it would be localhost:8080/users/users/. Same problem might be with /messages.
I am trying to most optimally structure the files of my Express app. And the Router module confuses me.
As far as I know, all queries should be in models folder.
This is my current desired setup (which does not work for my query.js and query2.js files, the error I get is that "App" is not defined).
When I put the query code (from query.js file) inside my App.js file directly, then it works however.
Also the setup I have works correctly for my Email routing.
How to fix?
Here my project structure:
project_structure
Here content of my files:
APP.JS
const express = require('express');
const request = require('request');
const requestPromise = require('request-promise');
const bluebird = require('bluebird');
const bodyParser = require('body-parser');
const cors = require('cors');
const app = express();
app.use(cors());
const router = require('./routes');
app.use(router);
function App(req, res) {
if (!req.url) {
req.url = '/';
req.path = '/';
}
return app(req, res);
}
module.exports.my_server = App;
INDEX.JS (in routes folder)
const express = require('express');
const router = express.Router();
const config = require('../config');
let email = require('../models/email');
const query = require("../models/query");
const query2 = require("../models/query2");
router.post('/api/subscribe', function (req, res) {
const data = {
subscribed: true,
address: req.body.email,
};
...
module.exports = router;
QUERY.JS (in models folder)
app.get('/query', function(req, res, next) {
request({
uri: 'https://queryapi.api/search?q=stuff&api-key=api_key',
qs: {
api_key: 'api_key',
}
}).pipe(res);
});
You don't have access to the variable app from your query.js.
You would want to export your methods from query.js instead so you can import them to your router like this:
EDIT: change http verb from .get to .post
replace:
app.get('/query', function(req, res, next) {
with
exports.post = function(req, res, next) {
and this is how you would assign the exported method query.post to route /api/subscribe/query
const query = require("./query");
router.post('/api/subscribe/query', query.post);
/* more end points below: */
// router.get(...
// router.put(...
// ...and so on
POST request on /api/subscribe/query
P.S: This works but things can quickly get ugly if you have more routes so it would be more maintainable if you restructure your source such that the main routes are expressed clearly in your app entry file; But that's another concern.
In index.js add this line.
router.use(query)
I'm doing to some refactoring in my application and I don't understand why this case is failing.
index.js
const express = require('express');
const router = express.Router();
const models = require('../models');
const listRoute = require('./list');
router.use('/list', listRoute);
list.js
const express = require('express');
const router = express.Router();
const models = require('../models');
const sendListDataToView = (req, res, view) => {
// get data from backend and pass to template
}
router.route('/list/show/:id')
.get((req, res) => {
sendListDataToView(req, res, 'view-list')
})
router.route('/list/expand-records-forms/:id')
.get((req, res) => {
sendListDataToView(req, res, 'edit-list-records')
})
module.exports = router;
Trying to navigate to /list/show/3 throws a 404 error. However, if I move the definitions of these routes and sendListDataToView to index.js, the page loads fine. Is this because of the multiple router.routes?
I'm just going to wipe my original answer.
You need to create the app.
const express = require('express');
const app = express();
const models = require('../models');
const listRoute = require('./list');
app.use('/list', listRoute); // Using express now.
app.listen(8080); // starts server