I have this router (http/api/ping.js):
var express = require('express');
var router = express.Router();
router.get('/ping', function (req, res) {
res.send("You called /api/ping");
});
module.exports = router;
This router is embedded into this router (http/api/index.js):
var express = require('express');
var router = express.Router();
router.get('/', function (req, res) {
res.send('You called /api');
});
router.use('/ping', require('./ping'));
module.exports = router;
And this router is used by my Express.js app (app.js):
var http = require('http');
var express = require('express');
var bodyParser = require('body-parser');
var logger = require('./config').logger;
// Create app
var app = express();
var server = http.createServer(app)
var io = require('socket.io')(server);
// App config
app.use(bodyParser.json());
app.use('/api', require('./http/api'));
// Display requests on console
app.use(function (req, res, next) {
logger.trace(req.method, req._parsedUrl.href);
next()
});
module.exports = {
app: app,
server: server
};
When I run the app, /api returns You called /api, but /api/ping gives me a 404.
I am using Node 6.9.1 and Express ^4.14.0
I think order matters in this scenario. Try putting /ping above the / get route.
router.use('/ping', require('./ping'));
router.get('/', function (req, res) {
res.send('You called /api');
});
Also in your ping route you say the path to your route is /ping you also say it is /ping when you import it to the other router, which would make the path /api/ping/ping
change
router.get('/ping', function (req, res) {
res.send("You called /api/ping");
});
to
router.get('/', function (req, res) {
res.send("You called /api/ping");
});
I think your routing is incorrect on this line
router.use('/ping', require('./ping'));
this will point to http/api/ping/ping
it should be
router.use('/', require('./ping'));
Related
app.js
const express = require("express");
const app = express();
app.use("/", require("./routers.js")(app));
app.listen(3000);
router.js
module.exports = function (app) {
console.log(app);
app.get("/", (req, res) => {
res.json(5);
});
};
The error given by the Console is: " TypeError: Router.use() requires a middleware function but got an undefined "
I don't understand why I can't pass the express app(app.js) through routers( in this way I don't redeclare the express and app variable in router.js ).
Don't pass app to routes better to create a new router and pass to the app.
router.js
const express = require("express");
const router = express.Router();
router.get("/", (req, res) => {
res.json(5);
});
module.exports = router;
app.js
app.use("/", require("./routers.js"));
As you mention in the comment, you don't have to add an inside app.use
module.exports = function (app) {
app.get("/", (req, res) => {
res.json(5);
});
};
// app.js
require("./routers.js")(app);
The use method of Express needs a callback of three parameters, not the app itself, so you need something like this:
In routes.js
exports.doSomeThing = function(req, res, next){
console.log("Called endpoint");
res.send("Called endpoint");
}
In your index.js
const Express = require("express");
const app = Express();
const routes = require("./routes");
app.use("/", routes.doSomeThing);
app.listen(3030, () => {
console.log("Listening on port 3030");
});
This approach doesn't need to include the express router but this may not be adecuate for big scale projects I recommend you to read express router documentation:
https://expressjs.com/es/guide/routing.html#express-router
I am using the express framework for a node.js backend server. I am using the express router to define the different routes.
This is my app.js file:
var express = require('express');
var app = express();
var server = require('http').Server(app);
var cors = require('cors');
app.use(cors());
app.use(express.json());
var route = require('./route');
app.use('/api/', route);
server.listen(3000, () => {
console.log('App running on port 3000!');
});
This is my router route.js:
var express = require('express');
var router = express.Router();
var controller = require('./controller');
router.use(function (req, res, next) {
next();
router.get('/test', function (req, res, next) {
controller.get(req, res, next);
});
});
module.exports = router;
The route itself uses a controller for the logic controller.js
exports.get = function (req, res, next) {
res.send('Hello World');
}
Starting the app with node app.js and calling the defined route http://localhost:3000/api/test will result in a Cannot GET /api/test on the first try. Calling the route a second time however will result in the expected answer hello world.
What is the reason for the first call failing? Why does it work on the second try? Any ideas are appreciated
Because router.use(function (req, res, next) { will only get executed on the first request, and when you call next() the route was not yet added. Afterwards you call router.get(...) which will add the route, so it will be available the next time.
Nevertheless thats just bad, move the .get(...) outside of .use(...) (you can also get rid of it entirely).
I'm basically trying to recreate this from Sinatra in Express:
get '/' do
redirect '/channels'
end
I'm trying to build a Node.js/Express.js app and am starting to incorporate an MVC structure. My app.js file contains my / route, as such:
app.js
app.get('/', function(req, res) {
res.redirect('/search');
})
I want it to redirect to the /search route in controllers/search.js, which contains the following:
controllers/search.js
const express = require('express');
const app = express();
app.get('/search', function(req, res) {
res.render('index.js');
})
The browser does redirect to localhost:3000/search but it displays Cannot GET /search. All of the tutorials and documentation I see about rerouting in Express don't show the whole file so I'm not able to tell if I have to require or export anything ala Node.js.
Any help is appreciated.
try this
server.js
var http = require('http');
var express = require('express');
var searchRouter = require('./searchRouter');
var app = express();
app.use('/', searchRouter);
var server = http.createServer(app);
server.listen(3000);
searchRouter.js
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
res.send('Nope, try /search');
});
router.get('/search', function(req, res, next) {
res.send('yeah!! you found me');
});
module.exports = router;
you can extend this logic by
app.use('/search', searchRouter);
in search router
// this handles /search
router.get('/', function(req, res, next) {}
//this handles /search/apple
router.get('/:id', function(req, res, next) {}
Utilizing express.Router() for API calls to/from our application:
var express = require('express');
var app = express();
var router = express.Router();
router.use console.logs before every API call:
router.use(function(req, res, next) { // run for any & all requests
console.log("Connection to the API.."); // set up logging for every API call
next(); // ..to the next routes from here..
});
How do we export our routes to folder/routes.js and access them from our main app.js, where they are currently located:
router.route('/This') // on routes for /This
// post a new This (accessed by POST # http://localhost:8888/api/v1/This)
.post(function(req, res) {
// do stuff
});
router.route('/That') // on routes for /That
// post a new That (accessed by POST # http://localhost:8888/api/v1/That)
.post(function(req, res) {
// do stuff
});
...when we prefix every route with:
app.use('/api/v1', router); // all of the API routes are prefixed with '/api' version '/v1'
In your new routes module (eg in api/myroutes.js), export the module.
var express = require('express');
var router = express.Router();
router.use(function(req, res, next) {
console.log('Connection to the API..');
next();
});
router.route('/example')
.get(function(req, res) { });
.post(function(req, res) { });
module.exports = router;
Then you can require the module in your main server/app file:
var express = require('express');
var app = express();
var myRoutes = require('./api/myRoutes');
app.use('/api', myRoutes); //register the routes
In your app.js file you can have the following:
//api
app.use('/', require('./api'));
In the folder api you can have 'index.js` file, where you can write something like this:
var express = require('express');
var router = express.Router();
//API version 1
router.use('/api/v1', require('./v1'));
module.exports = router;
In the folder v1 file index.js something like this:
var express = require('express');
var router = express.Router();
router.use('/route1', require('./route1'));
router.use('/route2', require('./route2'));
module.exports = router;
File route1.js can have the following structure:
var express = require('express');
var router = express.Router();
router.route('/')
.get(getRouteHandler)
.post(postRouteHandler);
function getRouteHandler(req, res) {
//handle GET route here
}
function postRouteHandler(req, res) {
//handle POST route here
}
module.exports = router;
route2.js file can have the same structure.
I think this is very comfortable for developing the node project.
So I'm trying to seperate my login routes in a seperate JS file called login_routes.js
I keep getting this specific error:
TypeError: Router.use() requires middleware function but got a Object
at Function. (/Users/ethanthomas/Desktop/mean-stuff/express-server/node_modules/express/lib/router/index.js:446:13)
Not entirely understanding what it's asking me to implement?
login_routes.js:
var express = require('express');
var app = express();
app.route('/login')
.get(function(req, res, next) {
res.send('this is the login form');
})
.post(function(req, res, next) {
console.log('processing');
res.send('proccessing the login form!');
});
server.js:
var express = require('express');
var app = express();
var path = require('path');
var adminRoutes = require('./app/routes/admin_routes');
var loginRoutes = require('./app/routes/login_routes');
app.use('/admin', adminRoutes);
app.use('/login', loginRoutes);
//send our index.html file to the user for the home page
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname + '/index.html'));
});
//start the server
app.listen(1337);
console.log('leet is the magic port');
Your login_routes.js should look something like this (in the context of express):
var express = require('express');
var router = express.Router();
// GET request to /login
router.get('/', function(req, res, next) {
// do something
});
// POST request to /login
router.post('/', function(req, res, next) {
// do something
});
module.exports = router;
In your app.js you use
var login_routes = require('./login_routes');
...
app.use('/login', login_routes);
...
Have a look at the code generated by the express-generator module. That is a starting point for express webserver apps.
People have already offered hints at the solution in comments.
The first issue is that you need to export your "sub" app from login_routes.js. To do so, change this:
var app = express();
Into this:
var app = module.exports = express();
Secondly, you are—probably unintentionally—creating routes for GET /login/login and POST /login/login. To solve this, use this in login_routes.js:
app.route('/').get(...).post(...);
This is because the root path in your sub app (the one in login_routes.js) will get mapped to the path used in app.use() in your main app (server.js).
Do like this:
login_routes.js:
exports.get = function( req, res ) {
res.send('this is the login form');
};
exports.post = function( req, res ) {
console.log('processing');
res.send('proccessing the login form!');
};
server.js:
var loginRoutes = require('./app/routes/login_routes');
app.get('/login', loginRoutes.get);
app.put('/login', loginRoutes.post);
login_routes.js:
var express = require('express');
var app = express();
app.route('/login')
.get(function(req, res, next) {
res.send('this is the login form');
})
.post(function(req, res, next) {
console.log('processing');
res.send('proccessing the login form!');
});
module.exports = router;
just writ module.exports = router then it will be work