General question.
I am looking to create a console-like application with Node.js that also has api capabilities. It will have timed task that will run on a schedule but also be available to send http request to. My problem is that while I've created the api. I don't know how to go about creating basic task to be performed on a schedule while the server stays running in case http request is made for different types of task.
Main idea is to have the task schedule to run while also keeping the server running and waiting for http request
Folder paths
folders
-controllers
-models
-modules
-node-modules
-routes
general files
app.js
package-lock.json
package.json
server.js
task.js
Proposed area for Scheduled task to be performed:
index.js
const { checkTablesForData, requestRoutine, runNecessaryUpdate } = require('./task')
function Main() {
...
\\task to be executed
\\Check the table for records to be processed
let obj = checkTablesForData();
\\Send third party request with object data. ie - id's
obj.map( id => {
\\call request routine
requestRoutine(id)
})
\\Run final process
runNecessaryUpdate(id)
}
task.js
checkTablesForData(){
...
}
requestRoutine(id){
...
}
runNecessaryUpdate(id){
...
}
module.exports = { runNecessaryUpdate, checkTablesForData, requestRoutine }
Code for api setup
app.js
const express = require('express')
const path = require('path')
const app = express() //, api = express();
const cors = require('cors');
const bodyParser = require('body-parser');
app.get('/', function(req, res){
res.redirect('./api')
})
const api = require('./routes/api');
app.use('/api', api)
module.exports = app
server.js
const app = require('./app');
const port = process.env.PORT || 3000;
app.listen(port, 'localhost', () => {
console.log(`Server is running on port ${port}`);
});
api.js
const express = require('express');
const router = express.Router();
//Controller Modules
const controller = require('../controllers/homeController');
//Routes
router.get('/request/:id', controller.post)
module.exports = router;
controller.js
//Send request to 3rd party api
export.post = function(req, res){
const options = {
....
}
return request(options)
.then( response => {
...
}
.catch( error => {
\\error routine
}
}
Advice is very much needed.
Thanks!
Related
I have written a simple request response code in NODEJS but there is no response in return of the request is there .
The code for my app.js(Server file) is
const express = require('express');
const cors = require('cors')
const paymentroute = require('./routes/paymentRoutes');
const app = express();
app.use(cors);
app.use("/api",paymentroute);
app.listen(3100,()=>{
console.log(`listening to port 3100`);
})
The code for my req and res is
const express = require('express');
const router = express.Router();
// const { checkout } = require('../controllers/paymentController');
router.post("/checkout",(req,res) => {
console.log("this function is called ")
return res.json({success:"true"})
});
module.exports = router;
Even the console.log inside the res function is not working.
Just change app.use(cors); to app.use(cors());
const express = require('express');
const cors = require('cors');
const paymentroute = require('./routes/paymentRoutes');
const app = express();
app.use(cors());
app.use('/api', paymentroute);
app.listen(3100, () => {
console.log(`listening to port 3100`);
});
I think it is a connection-related issue often related to a networking issue caused by a Virtual Private Network (VPN) that in some cases is required by some API services or, in other cases, prevents you to reach an API service.
The issue seems to be a combo of having the no-cache header enabled and a request URL length over 64 characters. If the issue persists after doing this solution then try to upgrade to the latest version of Postman.
I am trying to start my project via launching server.js but I am getting error:"cannot GET /"
even after I made an app.get() route in my server.js
I am using also "body-parser" as a middleware, and "cors"
server.js:
// Setup empty JS object to act as endpoint for all routes
const projectData = {};
// Require Express to run server and routes
const express = require('express');
// Start up an instance of app
const app = express();
/* Middleware*/
//Here we are configuring express to use body-parser as middle-ware.
const bodyParser = require('body-parser')
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// Cors for cross origin allowance
const cors = require('cors');
app.use(cors());
// Initialize the main project folder
app.use(express.static('views'));
const port = 8080;
app.use(express.static('dist'));
// Setup Server
const server=app.listen(port, ()=>{console.log(`running on localhost: ${port}`)});
app.get('/all', sendData);
function sendData (request, response) {
response.send(projectData);
};
// TODO-ROUTES!
app.post('/add', Info);
function Info(req, res) {
projectData['date'] = req.body.date;
projectData['temp'] = req.body.temp;
projectData['content'] = req.body.content;
res.send(projectData);
}
module.exports = server;
I made a POST request to /add and it works. Then I call GET /all and also work. The error cannot GET / is because you are requesting an endpoint that not exists.
Just add a dummy data to your Fn() if you want to see some output on GET request wihtout making any post request
Here is my solution
app.get('/', (req, res) => {
res.redirect('/all');
})
we need this because you do not have any root URL set, so we set the root URL to redirect to /all
2nd step then we add a dummy data in the projectData
var projectData = {
date = new Date().getDate();,
temp = 10,
content="This is Test Content"
}
This way when you call 'http://localhost:8080/' you shall get redirected to http://localhost:8080/all and instead of empty {} you shall see the dummy data.
I'm not getting expected results by including files in Nodejs. Here is my code:
Service Route File
const express = require('express');
const router = express.Router();
const path = require('path');
const config = require('../config');
const serviceAdapter = require('./serviceAdapter');
module.exports = (preRequestPath, serviceBaseUrl) => {
console.log("On server start", preRequestPath)
router.post('/*', (req, res) => {
console.log("On request", preRequestPath)
const axiosHttp = serviceAdapter(serviceBaseUrl);
axiosHttp.post(preRequestPath+req.path, req.body).then(resp => {
res.send(resp.data)
}).catch(err => {
res.status(404).sendFile(path.join(__dirname + '/../404.html'));
});
});
return router;
}
Main Server File
const express = require('express');
const userApiService = require('./routes/userService');
const userAdminService = require('./routes/userService');
app.use('/api/user_service/', userApiService("/api", config.userServiceUrl) );
app.use('/admin/user_service/', userAdminService("/admin", config.userServiceUrl) );
var server = app.listen(3000, function(){
console.log('Server listening on port 3000');
});
module.exports = server;
Expecting Console Result:
On server start /api
On server start /admin
On request /api (when hitting http://baseurl.com/api/<anything>)
On request /admin (when hitting http://baseurl.com/admin/<anything>)
But Getting Console Output as:
On server start /api
On server start /admin
On request /api (when hitting http://baseurl.com/api/<anything>)
On request /api (when hitting http://baseurl.com/admin/<anything>)
Both the time, returning /api path.
Can anyone tell me why is it happening and what's the solution?
You're creating only one router in userService.js (the first file). It's created once before the function so you really only end up with one router. The first time you require it the router gets created, but the second time you require it Node knows it was already loaded and it's not re-initialized. You should be creating a different router for each case like this:
const express = require('express');
// const router = express.Router(); <-- don't do it here
const path = require('path');
const config = require('../config');
const serviceAdapter = require('./serviceAdapter');
module.exports = (preRequestPath, serviceBaseUrl) => {
const router = express.Router(); // <--- create a new router for each case
console.log("On server start", preRequestPath)
router.post('/*', (req, res) => {
console.log("On request", preRequestPath)
const axiosHttp = serviceAdapter(serviceBaseUrl);
axiosHttp.post(preRequestPath+req.path, req.body).then(resp => {
res.send(resp.data)
}).catch(err => {
res.status(404).sendFile(path.join(__dirname + '/../404.html'));
});
});
return router;
}
Also in your main server file you only need to require it once. It's just a function to create the service so you don't need 2 different variables holding that function. So you can initialize both using the one function like this:
// const userApiService = require('./routes/userService');
// const userAdminService = require('./routes/userService');
const service = require('./routes/userService');
app.use('/api/user_service/', service("/api", config.userServiceUrl) );
app.use('/admin/user_service/', service("/admin", config.userServiceUrl) );
I'm making a nodeJS module, and I want to use expressJS as a framework for it.
I'm trying to see, how I could go by, including a function inside and app.get(); and call it via another file, such as the actual app.
var express = require("express");
var app = express();
app.get("/", function (req, res) {
exports.type = function (text) {
console.log(req.ip);
console.log(text);
}
});
now when I use this, and i call it on the actual app like:
var web = require("directory_to_file");
var express = require("express");
var app = express();
var http = require("http").Server(app);
app.get("/", function (req, res) {
web.type("Hello, world");
});
http.listen(10022, function () {
console.log("server is up");
});
I get an error:
TypeError: Property 'type' of object #<Object> is not a function
anyone know a way to make it so I can call the function?
There are generally two things you want to export as a module - an API and a Middleware. The classic example of middleware is an authentication module. To do the middleware, just export the middleware. I tend to do a little more than that so I can configure the middleware later. Something along the lines of this:
module.exports = exports = function(config) {
// Do something with config here
return function(req, res, next) {
// your middleware here
};
};
You can then use your middleware in your main program like this:
var app = require('express')(),
mymodule = require('./mymodule');
var config = {}; // replace with whatever config you need
app.use(mymodule(config));
app.listen(process.env.PORT || 3000);
To implement an API, you will create a Router object, then attach your routes to the Router object. You can then "mount" your router in your main program. For example, you could have a file called 'myroutes.js' with the following contents:
var express = require('express'),
myroutes = express.Router();
myroutes.get('/foo', (req, res) => {
res.status(200).type('application/json').send({ myparam: 'foo' });
});
module.exports = exports = myroutes;
Have the following in your main program:
var app = require('express')(),
myroutes = require('./myroutes');
app.use('/api', require('./myroutes'));
app.listen(process.env.PORT || 3000);
Here, in 'myroutes.js', I'm defining a sub-route of /foo and then in the main program, I'm mounting that on /api - so I would access /api/foo to access that API.
In your directory_to_file you are only exporting on app.get('/') which will never be called.
You could add in your directory_to_file the following code
var express = require('express');
var router = express.Router();
router.get('/', function(req, server) {
console.log(req.ip);
});
module.exports = router;
And in your main file you could use app.use('/', web)
A short explanation:
You are creating a new express app / config in your directory_to_file file which won't be launched or used. So your app.get event won't be fired once.
That's why web.type is not a function. You are not exporting anything.
Use the way I provided. This is a commonly used method.
You could call the code I provided a "route". Create multiple routes / route files and include them in your main method.
Your code just looks confused. If I understand you correctly, what you are really trying to do (at least in Node/express terminology) is write your own middleware.
Express is designed with this in mind and it's pretty straightforward e.g.
ipLogger.js
module.exports = function(req, res, next) {
console.log(req.ip);
next();
}
app.js
var http = require("http")
, express = require("express");
, app = express()
, server = http.Server(app)
, ipLogger = require("./ipLogger.js");
app.use(ipLogger()); // log IP of all requests
// handle routes
server.listen(10022, function() {
console.log("server is up");
});
I'm building a web app with Express and Node and am trying to factor my routing so that I don't have hundreds of routes in the same file. This site serves different files within the projects directory, so I made a file in routes/ called projectRoutes.jsto handle the routing for project files:
var express = require('express');
module.exports = function() {
var functions = {}
functions.routeProject = function(req, res) {
res.render('pages/projects/' + req.params.string, function(err, html) {
if (err) {
res.send("Sorry! Page not found!");
} else {
res.send(html);
}
});
};
return functions;
}
Then, in my routes.js, I have this...
var projectRoutes = require("./projectRoutes");
router.get('/projects/:string', function(req, res) {
projectRoutes().routeProject(req, res);
});
Is there a better way to structure this functionality within projectRoutes.js? In other words, how can I configure projectRoutes.js so that I can write the follow line of code in index.js:
router.get('/projects/:string', projectRoutes.routeProject);
The above seems like the normal way to handle something like this, but currently the above line throws an error in Node that says the function is undefined.
Thanks for your help!
You should use the native express router, it was made to solve this exact problem! It essentially lets you create simplified nested routes in a modular way.
For each of your resources, you should separate out your routes into several modules named <yourResource>.js. Those modules would contain all of the routing code as well as any other configuration or necessary functions. Then you would attach them in index.js with:
var apiRoute = router.route('/api')
apiRoute.use('/< yourResource >', yourResourceRouter)
For example, if you had a resource bikes:
In index.js:
var apiRoute = router.route('/api')
, bikeRoutes = require('./bikes')
apiRoute.use('/bikes', bikeRoutes)
Then in bike.js:
var express = require('express')
, router = express.Router()
, bikeRoutes = router.route('/')
bikeRoutes.get(function (req, res) {
res.send('api GET request received')
});
module.exports = bikeRoutes
From there its easy to see that you can build many different resources and continually nest them.
A larger of example of connecting the routes in index.js would be:
var apiRoute = router.route('/api')
, bikeRoutes = require('./bikes')
, carRoutes = require('./cars')
, skateboardRoutes = require('./skateboards')
, rollerskateRoutes = require('./rollerskates')
// routes
apiRoute.use('/bikes', bikeRoutes)
apiRoute.use('/cars', carRoutes)
apiRoute.use('/skateboards', skateboardRoutes)
apiRoute.use('/rollerskates', rollerskateRoutes)
Each router would contain code similar to bikes.js. With this example its easy to see using express's router modularizes and makes your code base more manageable.
Another option is to use the Router object itself, instead of the Route object.
In Index.js:
//Load Routes
BikeRoutes = require('./routes/Bike.js');
CarRoutes = require('./routes/Car.js');
//Routers
var express = require('express');
var ApiRouter = express.Router();
var BikeRouter = express.Router();
var CarRouter = express.Router();
//Express App
var app = express();
//App Routes
ApiRouter.get('/Api', function(req, res){...});
ApiRouter.use('/', BikeRouter);
ApiRouter.use('/', CarRouter);
In Bike.js:
var express = require('express');
var router = express.Router();
router.get('/Bikes', function(req, res){...});
module.exports = router;
Similarly in Car.js