Noob here. I'm trying to build an api server on Openshift using express. I also want to be able to serve static files from the /static folder. The problem is, I can't figure out how to set it up on Openshift. I've tried everything I can think of.
I have 2 server files, the app setup which calls a router.js file for the routes.
app.js
const express = require('express');
const http = require('http');
const bodyParser = require('body-parser');
const morgan = require('morgan');
const env = process.env;
const app = express();
const router = require('./router');
const mongoose = require('mongoose');
const cors = require('cors');
// DB Setup
// default to a 'localhost' configuration:
var connection_string = '127.0.0.1:27017/api:api';
// if OPENSHIFT env variables are present, use the available connection info:
if(env.OPENSHIFT_MONGODB_DB_PASSWORD){
connection_string = env.OPENSHIFT_MONGODB_DB_USERNAME + ":" +
env.OPENSHIFT_MONGODB_DB_PASSWORD + "#" +
env.OPENSHIFT_MONGODB_DB_HOST + ':' +
env.OPENSHIFT_MONGODB_DB_PORT + '/' +
env.OPENSHIFT_APP_NAME;
}
mongoose.connect('mongodb://' + connection_string);
// App Setup
app.use(morgan('combined')); //logging middleware
app.use(cors()); // allow cross origin requests
app.use(bodyParser.json({ type: '*/*'})); //read requests as json
-----> do I need to put something here ????
router(app);
// Server Setup
const port = env.NODE_PORT || 3090;
const ip = env.NODE_IP || 'localhost';
const server = http.createServer(app);
server.listen(port, ip);
console.log('Server listening on: ', port);
router.js
const Authentication = require('./controllers/authentication');
const passportService = require('./services/passport');
const passport = require('passport');
const requireAuth = passport.authenticate('jwt', { session: false});
const requireSignin = passport.authenticate('local', { session: false});
module.exports = function(app) {
app.post('/signup', Authentication.signup);
app.post('/signin', requireSignin, Authentication.signin);
app.get('/health', function (req, res, next ) {
res.writeHead(200);
res.end();
});
----> and/or something here?
}
Everything works except serving static files. Not sure if I need to put something in the app.js file as middleware, in the router file or both. Also not sure if I need to use Openshift environment variables? Can someone nudge me in the right direction?
In express you can serve static files by adding the following to your app.js using express.static()
var path = require('path');
// put this before all of your routes
app.use(express.static(path.join(__dirname, 'static')));
Related
I have a MEAN stack app hosted in Heroku. In my Express server, I use gzip (via compression middleware).
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const cors = require('cors');
const passport = require('passport');
const adminpassport = require('passport');
const mongoose = require('mongoose');
const config = require('./config/database');
// Connect to DB
mongoose.connect(config.database);
mongoose.connection.on('connected',()=>{
console.log('Connected to database '+config.database);
});
mongoose.connection.on('error',(err)=>{
console.log('DB Error '+err);
});
const compression = require('compression');
const app = express();
// Static Folder
app.use(express.static(path.join(__dirname, 'public')));
app.use(compression());
// Body Parser Middleware
app.use(bodyParser.json());
...
app.use(function(req, res) {
res.sendFile(path.join(__dirname, '/public', 'index.html'));
});
// Index Route
app.get('/', (req, res)=>{
res.send('Invalid enpoint');
});
app.listen(port, ()=>{
console.log("Server started on port "+port);
});
The problem is that the Angular main.js file (that is orginally 3.2mb, compressed to 575kb) is still seemingly being download as if it's still the uncompressed size. Here's an image of the load times:
I know my internet connection is fine (around 20mbps). Is there anything I'm missing? Is there something wrong in my implementation of gzip? Or even my Heroku dyno? This app is currently on the hobby dyno. I did change it to the professional one but didnt notice any difference.
I'm not sure what is your environment, but you can try this, is completely functional for me.
// Get dependencies
const express = require('express');
const path = require('path');
const http = require('http');
const bodyParser = require('body-parser');
const compression = require('compression');
const runApp = async() => {
const app = express();
app.use(compression({
filter: function (req, res) {
return (/json|text|javascript|css|font|svg/).test(res.getHeader('Content-Type'));
},
level: 9
}));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));
app.get('*', (req, res) => {
console.log('Front end called');
res.sendFile(path.join(__dirname, 'public/index.html'));
});
/**
* Get port from environment and store in Express.
*/
const port = process.env.PORT || '8081';
app.set('port', port);
/**
* Create HTTP server.
*/
const server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port, () => console.log(`API running on localhost:${port}`));
};
runApp();
This is my code i tried to send a request through http://localhost:3000/api/post/article using postman but i received cannot get as error.
It's working without using router.get but instead using app.get, so i think the problem is with the router.
This is the server.js file
const http = require("http");
const app = require("./app");
app.set("port", process.env.PORT || 3000);
const server = http.createServer(app);
server.listen(process.env.PORT || 3000);
this is the app file
const express = require("express");
const postRoutes = require("./routes/post");
const app = express();
app.use("api/post", postRoutes);
module.exports = app;
This is the router file
const express = require("express");
const router = express.Router();
const postCtrl = require("../controllers/post");
router.get("/article", postCtrl.specArticle);
module.exports = router;
This is the controller file
module.exports.specArticle = (req, res) => {
res.status(200).json({ message: "working currently" });
};
Change this:
app.use("api/post", postRoutes);
to this:
app.use("/api/post", postRoutes);
As best I know, all paths in your route handlers should start with / (at least I have no idea why you would ever not start them with a /).
In my node/express app, I have the following app.js file with the following routing
const express = require('express');
const path = require('path');
const logger = require('./middleware/logger');
const cors = require('cors');
const bodyParser = require('body-parser');
const app = express();
app.use(cors());
app.use(express.static(path.join(__dirname,'public')));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:false}));
app.use(express.json());
app.use(express.urlencoded({extended:false}));
app.use('/wsserver', require('./routes/wsroutes'));
app.use('/', require('./routes/company'));
const port = process.env.PORT || 3000;
app.listen(port, ()=>{
console.log('server runs on port ', port);
});
Every request that goes to http://localhost:8080/wsserver, is handeld by wsroutes. I am planning to setup a websockets server in there, but for now contains
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => {
res.send('ws');
})
module.exports = router;
The / handles all the other requests and its handled by the company that contains
router.get('/',(req, res)=>{ ....
router.get('/:companyName/:id?/:employ?',(req, res)=>{ ...
etc
As you can guess, the problem is that when I go to http://localhost:8080/wsserver, is handled by the / route and the company route. I get the interface and the message no company named wsserver , because the wsserver becomes an argument in the router.get('/:companyName/:id?/:employ?' route.
How can I still have both routes, not change the / one and have them both work correctly? I tried to change positions in the routes like so
app.use('/', require('./routes/company'));
app.use('/wsserver', require('./routes/wsroutes'));
ans still nothing.
What else can I do ?
Thanks
I am hosting postgres database and app on Heroku. Express Router was working on my local host. Since I have deployed to Heroku I get ERROR on index route. But URL routes work when typed in.
I have tried making sure the PORT is setup correctly.
I have tried testing to see if Express/Router actually works by changing routes.
I have tried the other answers on stack overflow.
I have checked my proct file.
app.js
```
const express = require("express")
const app = express()
const path = require('path')
const PORT = process.env.PORT || 8080
const mustacheExpress = require("mustache-express")
const blogsRouter = require('./routes/blogs')
app.use(express.urlencoded({ extended: false }))
const VIEWS_PATH = path.join(__dirname, '/views')
app.use("/css", express.static(__dirname + '/css'))
app.engine("mustache", mustacheExpress(VIEWS_PATH + '/partials', '.mustache'))
app.set("views", VIEWS_PATH)
app.set("view engine", "mustache")
app.use('/blogs', blogsRouter)
app.listen(PORT, () => {
console.log("Hey Nick the server is running...")
})```
blogs.js //Routes folder
```const express = require('express')
const router = express.Router()
const bcrypt = require('bcrypt')
const SALT_ROUNDS = 10
const session = require('express-session')
const checkAuth = require("../utils/checkAuth")
const pgp = require('pg-promise')();
const connectionString = '#postgress host string is here'
const db = pgp(connectionString);
```
Do not know whats causing Express Router not to work on Heroku.
The following is my ./server.js my angular dist is at ./client/dist when I node server.js in the terminal my angular app and nodejs backend works as expected. Now how do I deploy on aws beanstalk (im open to changing beanstalk)?
Most tutorials want me to start the job from scratch but i really need the server to work as shown below like it does on localhost.
const express = require('express');
const colors = require('colors');
const bodyParser = require('body-parser');
const compression = require('compression');
const path = require('path');
const fs = require('fs');
const cors = require('cors');
// init "app"
const app = express();
var staticRoot = __dirname + '/client/dist/';
app.set('port', (process.env.PORT || 5000));
app.use(cors({origin: `http://localhost:4200`}));
//parse incoming data before routes
app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
// api routes
app.use('/api',require('./api/api'));
app.use(function(req, res, next) {
//if the request is not html then move along
var accept = req.accepts('html', 'json', 'xml');
if (accept !== 'html') {
return next();
}
// if the request has a '.' assume that it's for a file, move along
var ext = path.extname(req.path);
if (ext !== '') {
return next();
}
fs.createReadStream(staticRoot + 'index.html').pipe(res);
});
app.use(express.static(staticRoot));
app.listen(app.get('port'), function() {
console.log('app running on port', app.get('port'));
});
I created a modern MEAN Stack guide with full tutorials and source code. For your question in particular, I created a step-by-step guide on how to deploy a MEAN stack app to AWS Elastic Beanstalk (https://www.meankit.io/guides/deploy-with-aws)
There's also reference links as well if you need further information.