Deploy SQL Server api with Express.js to Heroku - node.js

I'm very new with Express.js, but right now i've created an api of SQL Server DB. It works fine on localhost, but now, i've deployed on Heroku. While my CMD prompt is open, my api works fine, but when it's close, i get an Internal Server Error.
Previously, i've created a test using Mongo as DB, mongoose and deployed to Heroku an the api still working even when the prompt isn't open. Someone knows if i have to create another .js document just like in mongoose or else to keep working my api?
This is my code on the .js document (server.js):
const express = require('express');
const bodyParser = require('body-parser');
const sql = require('mssql');
const app = express();
app.use(bodyParser.json());
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, contentType,Content-Type, Accept, Authorization");
next();
});
const dbConfig = {
user: "daUser",
password: "daPass",
server: "daServer",
database: "DaDB"
}
const executeQuery = function (res, query) {
sql.connect(dbConfig, function (err) {
if (err) {
console.log(err);
res.send(err);
}
else {
// create Request object
var request = new sql.Request();
// query to the database
request.query(query, function (err, result) {
if (err) {
console.log(err);
res.send(err);
}
else {
res.send(result);
}
});
}
});
}
app.get("/api/HolidayBaseApi", function (req, res) {
var query = "SELECT * FROM [HolidaysBase]";
executeQuery(res, query);
})
const PORT = process.env.PORT || 8080
app.listen(PORT, () => {
console.log("App now running on port", PORT);
});
My package.json next:
{
"name": "holidaysbaseapi",
"version": "1.0.0",
"description": "Api of Holidays",
"main": "server.js",
"scripts": {
"start": "node server.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Chuck Villavicencio",
"license": "ISC",
"dependencies": {
"body-parser": "^1.18.3",
"express": "^4.16.4",
"mssql": "^4.3.0"
},
"engines": {
"node": "8.11.3",
"npm": "5.6.0"
}
}
On Heroku i've installed the Heroku CLI; logged in, Clone the repository and deployed my changes.
I'm using Express.js, Node, SQL Server and Heroku

The problem is that your SQL server db is created on you local machine and heroku can't connect to it. You can you the postgresDB provided by heroku or create the sql server db in any provider around the internet and replace the dbConfig with the configs of that db

Related

Next Js cannot find module next

I created Next Js project. I deployed it to my CPanel. And I created server.js file on directory.
I called next module as require in server.js. But When I access to my website I catch an error.
internal/modules/cjs/loader.js:638
throw err;
^
Error: Cannot find module 'next';
This error message.
My server.js code
const { createServer } = require("http");
const { parse } = require("url");
const next = require("next");
const dev = process.env.NODE_ENV !== "production";
const port = !dev ? process.env.PORT : 3000;
// Create the Express-Next App
const app = next({ dev });
const handle = app.getRequestHandler();
app
.prepare()
.then(() => {
createServer((req, res) => {
const parsedUrl = parse(req.url, true);
const { pathname, query } = parsedUrl;
handle(req, res, parsedUrl);
console.log("pathname", pathname);
}).listen(port, (err) => {
if (err) throw err;
console.log(`> Ready on http://localhost:${port}`);
});
})
.catch((ex) => {
console.error(ex.stack);
process.exit(1);
});
My package json
{
"name": "projectName",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "node server.js",
"build": "next build",
"start": "NODE_ENV=production node server.js"
},
"dependencies": {
"express": "^4.17.1",
"next": "10.0.6",
"react": "17.0.1",
"react-dom": "17.0.1"
}
}
What should i do?
Thank you.
Best regards
Add this in your package.json dependency section : "#next/env": "^12.0.7"
I've already had problems publishing a next application other than on vercel. To fix the error I had to create a docker in order to publish the application. In case someone doesn't answer with a more viable solution, I recommend looking into using a docker.

Heroku Deployment not working with MongoDb

I created one demo app with ReactJS, NodeJS, MongoDb and Express. Trying to deploy on heroku. It works fine, if i dont use mongo, but as soon as i introduced mongo db. I am getting error cannot GET /.
I am using mongodb atlas. Do I need heroku addon to use database?
server.js
// Import dependencies
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const path = require('path');
const MongoClient = require("mongodb").MongoClient;
const ObjectId = require("mongodb").ObjectID;
const mongodb = require('mongodb');
const fs = require('fs');
const moment = require("moment");
require('dotenv').config();
const CONNECTION_URL = process.env.MONGODB_URI || "mongodb+srv://<username>:<password>#cluster0.xzzno.mongodb.net/<dbname>?retryWrites=true&w=majority";
const DATABASE_NAME = "DBNAME";
const port = process.env.PORT || 5000;
const app = express();
// Set our backend port to be either an environment variable or port 5000
// This application level middleware prints incoming requests to the servers console, useful to see incoming requests
app.use((req, res, next) => {
console.log(`Request_Endpoint: ${req.method} ${req.url}`);
next();
});
// Configure the bodyParser middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
// Configure the CORs middleware
app.use(cors());
app.get("/test/", (request, response) => {
response.send({"name":"Hello Test!!!"});
});
var database, userSignUp;
app.listen(port, () => {
MongoClient.connect(CONNECTION_URL, { useNewUrlParser: true }, (error, client) => {
if(error) {
throw error;
}
database = client.db(DATABASE_NAME);
userSignUp = database.collection("UserData");
console.log("Connected to `" + DATABASE_NAME + "`!");
});
})
package.json
{
"name": "testproject",
"version": "1.0.0",
"description": "Learning Deployment",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"client": "cd client && npm start",
"server": "nodemon server.js",
"dev": "concurrently --kill-others-on-fail \"npm run client\" \"npm run server\"",
"client:build": "cd client && npm run build"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Username/TestProject.git"
},
"author": "Ankita Jaiswal",
"license": "ISC",
"bugs": {
"url": "https://github.com/Username/TestProject/issues"
},
"homepage": "https://github.com/Username/TestProject#readme",
"dependencies": {
"body-parser": "^1.19.0",
"concurrently": "^5.3.0",
"cors": "^2.8.5",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"nodemon": "^2.0.7",
"moment": "^2.29.1",
"mongodb": "^3.6.3",
"mongoose": "^5.11.8"
}
}
procfile
web: npm run dev
have tried web: npm start as well.
Just from my limited experience, I've had the same issue and it turned out I forgot to configure my environment variables on Heroku, so my MONGO_URI was undefined. If not that, you can use the Heroku CLI and run heroku logs --tail from the root of your project and might be able to see more about what's going on.
const CONNECTION_URL = process.env.MONGODB_URI || "mongodb+srv://<username>:<password>#cluster0.xzzno.mongodb.net/<dbname>?retryWrites=true&w=majority";
The upper code is incorrect. You have to change < username > and < password > (both include < >) by your usename and your password! Example:
const CONNECTION_URL = process.env.MONGODB_URI || "mongodb+srv://kanechan25:kane02052409#cluster0.xzzno.mongodb.net/<dbname>?retryWrites=true&w=majority";

My fullsatck JS application does not work in production on Heroku

I have created my first FullStack JS app. REACT for the front port :3000, NODE for the Back port 3001 and postgresql for database. And is also the first time I use Heroku !
My app called philosophybooks my database postgres is livres with one table books on this table 13 rows, 13 books in my db it's just for exemple :
author, title, date_of_parution, cover cover is just a string I've a folder illustrations_books in my frontend part of my app in this folder I have all images of the cover book
With CLI on windows I have well push all my app with my database all is well on Heroku. In front I've run a build folder and I have copy this one in back part of my app.
When I start heroku local web all work perfectly on http:localhost:5000
but when I launch my app not locally I have a console error
GET https://philosophybooks.herokuapp.com/livres 503 (Service Unavailable)
in front part in package.json I've"proxy": "http://localhost:3001"
little part of index.js
...
app.use(express.static('build'))
...
//Entry point API
app.get('/', (req, res) => {
res.send('My app is well connected and endpoint is OK')
})
//READ ALL
app.get("/livres", (req, res) => {
pool.query('SELECT * FROM books ORDER BY id ASC', (err, results) => {
if (!err)
res.status(200).json(results.rows)
else
console.log(err)
})
})
...
...
const port = process.env.PORT || 3001
app.listen(port, () => {
console.log(`[Express] is running on port ${port}`)
})
Little part of Livres.jsx in front part
...
...
useEffect(() => {
const fetchData = async () => {
setIsError(false)
try {
const result = await axios('/livres') /* 'http://localhost:3001/livres' */
setData(result.data)
} catch (error) {
setIsError(true)
console.log(error)
}
}
fetchData()
}, [])
...
...
config.js
require('dotenv').config()
const { Pool } = require('pg')
/* const pool = new Pool({
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
host: process.env.DB_HOST,
port: process.env.DB_PORT,
database: process.env.DB_DATABASE,
}) */
const isProduction = process.env.NODE_ENV === 'production'
const connectionString = `postgresql://${process.env.DB_USER}:${process.env.DB_PASSWORD}#${process.env.DB_HOST}:${process.env.DB_PORT}/${process.env.DB_DATABASE}`
const pool = new Pool({
connectionString: isProduction ? process.env.DATABASE_URL : connectionString,
ssl: isProduction,
})
module.exports = { pool }
I have also a Procfile file web: node index.js
package.json backend part
{
"name": "philosophybooks",
"version": "1.0.0",
"description": "bibliothéque philosophique",
"main": "index.js",
"engines": {
"node": "12.x",
"npm": "6.x"
},
"scripts": {
"start": "nodemon index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"NODEJS",
"JAVASCRIPT",
"ES6"
],
"author": "LC",
"license": "ISC",
"dependencies": {
"compression": "^1.7.4",
"cors": "^2.8.5",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"helmet": "^4.1.1",
"nodemon": "^2.0.4",
"path": "^0.12.7",
"pg": "^8.3.3"
}
}
Render heroku local web
Render in prodhttps://philosophybooks.herokuapp.com/
I have to make a mistake that I don’t see or forget something, can you help me? if you need to see something else tell me. Thank you in advance for your help
EDIT Octobre 18, 2020
My database on HEROKU and via CLI pg:psql
Bonjour Parad0xJ,
PROBLEM:
It wasn't working because you were assigning an ssl certificate that wasn't verified. If you look at the heroku error carefully you will notice this error.
Error: self signed certificate
'DEPTH_ZERO_SELF_SIGNED_CERT'
const pool = new Pool({
connectionString: isProduction ? process.env.DATABASE_URL : connectionString,
ssl: isProduction, <=========== unverified self signed certificate
})
SOLUTION
Get rid of the ssl property in your pool configuration. Heroku already provides you a ssl so all you have to do is determine whether you want to disable or require it. You can read more here
const pool = new Pool({
connectionString: isProduction ? process.env.DATABASE_URL : connectionString,
sslmode: isProduction ? "require" : "disable"
})
Also you need to add the * route to the bottom because when it is at the top no other routes can be access:
app.get('*', (req, res) => { //<=========== Should be at the bottom of all routes
res.sendFile(path.join(__dirname, "frontend/build/index.html"));
});
Here is all the configuration in this git repo :
https://github.com/l0609890/philosophybook/invitations

Heroku 503 Service Unavailable

I am currently building a simple CRUD app using ExpressJS, and host it on Heroku using free account.
The problem I ran into is:
GET API for getting all items works on localhost, but show status 503 when hosting on Heroku;
POST API for updating one item works on localhost, but same issue as GET API above;
All 503 errors are after 30s of loading, this should be a setting from Heroku.
I do have other API end points that work on both local and Heroku server:
GET API for getting one item using ID
My guessing:
The issue should not be a code issue
There is some issue when the code is deployed and Heroku cannot process this request
I tried to find some articles on the web but this seems hard to diagnose, anyone who has experience please let me know how I can solve this issue. Appreciate your comments.
My Mongoose Schema
const mongoose = require("mongoose");
const ThoughtSchema = mongoose.Schema({
title: {
type: String,
required: true
},
content: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
}
});
module.exports = mongoose.model("Thought", ThoughtSchema);
2 end points that do not work
// Returns all thoughts
router.get("/", async (req, res) => {
try {
const thought = await Thought.find();
res.json(thought);
} catch (err) {
res.json({ message: err });
}
});
// Submit a post
router.post("/", async (req, res) => {
const thought = new Thought({
title: req.body.title,
content: req.body.content
});
try {
const savedThought = await thought.save();
res.json(savedThought);
} catch (err) {
res.json({ message: err });
}
});
The end point that works
// Specific thought
router.get("/:thoughtId", async (req, res) => {
try {
const thought = await Thought.findById(req.params.thoughtId);
res.json(thought);
} catch (err) {
res.json({ message: err });
}
});
My package.json for this express app
{
"name": "my-thoughts-app",
"version": "0.1.0",
"description": "An app to records user's thoughts",
"main": "index.js",
"scripts": {
"start": "node index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/PayneTang/my-thoughts-app.git"
},
"author": "Payne Tang",
"license": "ISC",
"bugs": {
"url": "https://github.com/PayneTang/my-thoughts-app/issues"
},
"homepage": "https://github.com/PayneTang/my-thoughts-app#readme",
"dependencies": {
"dotenv": "^8.2.0",
"express": "^4.17.1",
"mongoose": "^5.8.11"
},
"devDependencies": {
"typescript": "^3.7.5"
}
}
EDIT:
My index.js
const express = require("express");
const path = require("path");
const app = express();
const mongoose = require("mongoose");
const thoughtRoute = require("./routes/thought");
require("dotenv").config();
console.log(process.env);
// Mongoose settings
mongoose.connect(
process.env.DB_CONNECTION,
{ useNewUrlParser: true, useUnifiedTopology: true },
() => {
console.log("Connected to DB!");
}
);
app.use(express.json());
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "*");
res.header(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept"
);
next();
});
app.use("/api/thought", thoughtRoute);
app.get("/api/test", (req, res) => {
res.send("hi");
});
// Serve client side
app.use(express.static(path.join(__dirname, "client/build")));
app.use(express.static(path.join(__dirname, "client/public")));
// app.get("*", (req, res) => {
// res.sendFile(path.join(__dirname, "client/build/index.html"));
// });
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
console.log("Listening on port " + PORT + "...");
});
The root cause after checking is due to the access restriction from Heroku to Mongo atlas.
After adding 0.0.0.0/0 for IP whitelist, I am able to get data from MongoDB.
Reference: https://docs.atlas.mongodb.com/security-whitelist/#add-whitelist-entries
I had the same problem and I was able to fix it by doing these two steps:
Add node version to package.json file:
"engines": {
"node": "14.17.3"
}
}
I changed access settings in MongoDB, allowing access to the database from anywhere (basically, whitelisting 0.0.0.0/0 IP address)
In my case, the issue was in package.json I installed two new packages yesterday and in my package.json:
"engines": {
"node": "12.16.0"
},
I changed the version to the my current system version:
"engines": {
"node": "14.5.0"
},
this is how my 503 service unavailable error gone.
This can be caused in several ways to the Node app.
1- Make sure that you specify the right port as what heroku does is it runs our app on a dynamic port.
const PORT = process.env.PORT || 3000;
app.listen(PORT, err => {
if(err) throw err;
console.log("%c Server running", "color: green");
});
as described in this comment
https://stackoverflow.com/a/52992592/11887902
2- Make sure that you added the Procfile with
npm start
to start the application.
3- If you are using Nodemon and you install it globally, just make sure that you install it locally too.
Finally, just have a look at the logs of the project to figure what heppen to make your project not in the service.
These cases happened to me and caused this error.
My issue was caused due to case sensitivity that is at times ignored by node,
in my controllers I had a file named sessions.js yet when importing in my routes I had mistakenly put ... = require('../controllers/Sessions'),
Nodemon was running without issues as I was developing but upon deploying on heroku it crashed so I changed to ... = require('../controllers/sessions')
and now it runs ok

node server.js return nothing

I'm very new to Node. I just installed it via Brew and when I ran node server.js in the Terminal, the Terminal does nothing for hours.
node -v
v6.6.0
This is the server file, it is from a tutorial video that I'm watching. The point of this simple express server is to allow me the ability to quickly serve test data via HTTP to the front-end.
package.json :
{
"name": "simple-server",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node server.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"body-parser": "^1.14.1",
"express": "^4.13.3",
"path": "^0.12.7"
}
}
server.js file :
var express = require('express');
var path = require('path');
var bodyParser = require('body-parser');
var app = express();
//Allow all requests from all domains & localhost
app.all('/*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Methods", "POST, GET");
next();
});
app.use(express.static(path.join(__dirname + '/public')));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
var persons = [
"person1.jpg",
"person2.jpg",
"person3.jpg",
"person4.jpg",
"person5.jpg",
"person6.png"
];
app.get('/persons', function(req, res) {
console.log("GET From SERVER");
res.send(persons);
});
app.listen(6069);
Thanks in advance
Try adding a console.log("started!") before app.listen. I'm guessing the server starts, but as is seen in your code, the only log it does is when it receives a request.
Try accessing http://localhost:6069/persons in your browser.
Edit: this defines a server response
app.get('/persons', function(req, res) {
console.log("GET From SERVER");
res.send(persons); <-- server sends persons array to client
});

Resources