adding mongoDB to web app that is working with postgreSQL - javascript

I have a simple web applicatoin with nodeJS backend and postgreSQL database.
I need to add a mongoDB database that will also save the state off the application as backup.
Is it possible to add it without changing the app structure in a simple way?
my code:
postgres.js file:
const Pool = require('pg').Pool
const pool = new Pool({
user: 'postgres',
host: 'localhost'
database: 'tasks',
password: 'password',
port: 5432,
});
const getTasks = (request, response) => {
// get tasks query
};
const getTaskById = (request, response) => {
// get task by id query
};
const createTask = (request, response) => {
// create task query
};
const updateTask = (request, response) => {
// update task query
};
const deleteTask = (request, response) => {
// delete task query
}
module.exports = {
getTasks,
getTaskById,
createTask,
updateTask,
deleteTask
};
index.js file:
const express = require('express')
const bodyParser = require('body-parser')
var cors = require('cors')
const app = express()
const port = 8080
const db = require('./db/postgres')
app.use(cors());
app.use(bodyParser.json());
app.use(
bodyParser.urlencoded({
extended: true,
})
);
app.get('/', (request, response) => {
response.json({ info: 'Node.js, Express, and Postgres API' })
});
app.get('/tasks', db.getTasks);
app.get('/tasks/:id', db.getTaskById);
app.post('/tasks', db.createTask);
app.put('/tasks/:id', db.updateTask);
app.delete('/tasks/:id', db.deleteTask);
app.listen(port, () => {
console.log(`App running on port ${port}.`)
});
Thanks!

How complicated is the state of the application and how do you intend on keeping it updated? Perhaps using MongoDB as store for state snapshots is over-complicating things. Storing JSON in Redis is possibly a simpler route.
You should perhaps also ask yourself why you need to save the sate of the application if you already have the postgres database. What state does your backend produce that is auxiliary to the data in postgres?

Related

Fetch Data from Snowflake to nodejs

I am trying to design an API using Snowflake and Nodejs. For that I am using the following things :
Express
ejs
snowflake-sdk (nodejs module)
I want to fetch data from snowflake and want to display it on my ejs webpage. Please help if anyone has fetched data and populated it on a webpage using nodejs and snowflake.
this is my server.js file
const express = require("express");
const app= express();
const sql = require("./snowflake");
app.use(express.static("public"));
app.use(express.urlencoded({ extended: true}));
app.set("view engine","ejs");
app.get("/", function(request,response){
response.render("index");
});
app.get("/request/:core", async function(request,response){
let core=await sql.getCore(request.params.core_name);
response.render("request",{request: core});
});
const http = require('http');
const port=3000;
const server=http.createServer(function(req,res){
})
const listener = app.listen(port,function(error){
if(error){
console.log("Something went wrong due :", error);
}
else{
console.log('Server is listening port '+port);
}
})
This is my database.js file. I am able to connect to snowflake and run queries but can't understand, how to fetch the query result on the ejs webpage.
const { initParams } = require('request');
const sql = require('snowflake-sdk');
const connection = sql.createConnection({
account: 'account_name',
authenticator: 'SNOWFLAKE',
username: 'username',
password: 'password',
database: 'database',
schema: 'schema'
});
module.exports.getCore = async() =>{
connection.execute({
sqlText: 'Select column from Table_name',
complete: async function(err,stmt,rows){
let pool= await sql.connect();
return rows;
}
})
}
There is a sample application that you can try to compare, is written on node.js. It is a Citi Bike dashboard that lets users view bike usage over time and in differing weather conditions. The source code is available on GitHub.
More details: https://quickstarts.snowflake.com/guide/data_app/#4

express API extract data from URL

My api recives every 45 minutes a request:
GET http://MyHost/mediciones/sigfox_libelium/{device}/{data}/{time}/{customData#trama}
I want my code to save {device}, {data}, {time} and {customData#trama} into different variables so I can parse it into readable values(all data it is send hexadecimal) and insert them into my database.
How do I take those values out of the URL?
Also, what is the purpose of req, res? I guess It stands for request, respond.Respond sends back to the client but, request? I dont really understand how it works. Im learning all this new, hope someone can help.
This is my API code, I tried it with postman and it works fine so far:
const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const Pool = require("pg").Pool;
const pool = new Pool({
user: "mgr#stanpgtest",
host: "stanpgtest.postgres.database.azure.com",
database: "my db name",
password: "my pass",
port: 5432
});
const app = express();
app.use(cors());
app.use(bodyParser.json());
app.listen(8000, () => {
console.log(`Server is running, listening to port 8000`);
});
app.post("mediciones/sigfox_libelium/{device}/{data}/{time}/{customData#trama}", (req, res) => {
const { label, status, priority } = req.body;
pool.query(
"select now()",
(error, results) => {
if (error) {
throw error;
}
res.send(results);
}
);
});
You need to write the path in this format, then extract your params from req.params.
app.post("mediciones/sigfox_libelium/:device/:data/:time/:customData", (req, res) => {
const {device, data, time, customData} = req.params
}
I'm not sure what #trama is meant to be, but I guess you can't use # in the route pattern.

Is there a way to have a GET request with setInterval on the backend without the help of the client side/frontend?

I have this GET request that fetches data from a third party api. I want to check if there is new data every 5-10 minutes or so. Right now i have this setup on my backend.
exports.get_alerts = async (req, res) => {
const alertsUrl = `https://www.g2smart.com/g2smart/api/alert?cpo=${req.params.cpo}&status=Opened&limit=10&page=1`;
const axios = require("axios");
const auth = await refreshToken;
const currTime = moment().subtract(1, "days").format("X");
const newAlertsData = [];
const availableUsers = await axios.get(
"http://localhost:5000/api/schedule/available"
) ....
and on the front end i have this code to send a get request to my alerts api endpoint.
getAlerts = async () => {
axios
.get("/api/alerts/total_fr_hpc")
.then((response) => console.log(response.data))
.catch((err) => console.log(err));
};
timer = (time) => {
const date = new Date(time);
return `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`;
};
componentDidMount() {
this.alertsInterval = setInterval(this.getAlerts, 900000);
}
componentWillUnmount() {
clearInterval(this.alertsInterval);
My question is can i have all this done on the backend only? I read a bit about websockets but that seems to be only for a continuous 2way connection between the backend and frontend.
I'd like to have something like that towards my third party apis on the node/express server, either fetching data at a set interval or a continuous connection checking for new data without having to make GET requests from my frontend. I want to be able to get new Data and store it into MongoDB even when there is nobody logged in to the client side.
I want that the data the users get is always up to date without having at least one person logged in to trigger the GET requests.
This is how my node/express server is currently setup
const express = require("express");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const passport = require("passport");
const cors = require("cors");
const path = require("path");
const indexRouter = require("./routes/index");
const apiRouter = require("./routes/api"); //Import routes for "api" area of site
const app = express();
// CORS Middleware
app.use(cors());
app.options("*", cors());
// Bodyparser middleware
app.use(
bodyParser.urlencoded({
extended: false,
})
);
app.use(bodyParser.json());
// DB Config
const db = require("./config/keys").mongoURI;
// Connect to MongoDB
mongoose
.connect(db, {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
})
.then(() => console.log("MongoDB successfully connected"))
.catch((err) => console.log(err));
// Passport middleware
app.use(passport.initialize());
// Passport config
require("./config/passport")(passport);
// Routes
// Add api routes to middleware chain.
app.use("/", indexRouter);
app.use("/api", apiRouter);
// Serve static assets (build folder) if in production
if (process.env.NODE_ENV === "production") {
// Set static folder
app.use(express.static("client/build"));
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "client", "build", "index.html"));
});
}
const port = process.env.PORT || 5000;
app.listen(port, "0.0.0.0", () =>
console.log(`Server up and running on port ${port} !`)
);
I am not familiar with the axios as I always use the native fetch API. Maybe the isomorphic fetch can help.

Cant connect to specific database and collection inside mongoDB Atlas Cluster

I am creating a MERN stack application and have chosen to use mongoose to communicate with MongoDB Atlas. But MongoDB Atlas uses clusters with databases inside which again has collections. I cant find any documentation for how to connect to a specific database and collection.
this is my current code:
File with the schema
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const userSchema = new Schema({
User: {
fisrtname: String,
lastname: String,
email: String,
password: String,
},
Todos: [
{
title: String,
completed: Boolean,
id: Schema.Types.ObjectId,
},
],
});
module.exports = mongoose.model('User', userSchema, 'todosCollection');
Main server file
const express = require('express');
const path = require('path');
const mongoose = require('mongoose');
const dbConfig = require('./database/db');
const app = express();
const PORT = process.env.PORT || 8080;
// Connecting to MongoDB database
mongoose.Promise = global.Promise;
mongoose
.connect(dbConfig.db, {
useNewUrlParser: true,
})
.then(
() => console.log('Database Sucsessfully connected!'),
err => console.error('Could not connect to database: ' + err)
);
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'public', 'index.html'));
});
app.use('/api/todos', require('./routes/api/todos'));
app.listen(PORT, () => console.log(`Server is running on port ${PORT}`));
And the function who searches MongoDB
! This is a snippet from another file but the rest is unimportant to the question.
const userSchema = require('../../database/models/User');
router.get('/', (req, res) => {
userSchema.find((err, data) => {
if (err) {
res.staus(500).json({ msg: 'Did not found database data' });
} else {
res.json(data);
}
});
});
Once you have connected with your Atlas MongoDB cluster - you can treat it the same as any other MongoDB connection. See my answer on how to correctly connect to an Atlas cluster: https://stackoverflow.com/a/61480485/8322220.
However, you also seem to be having an issue querying your data, but it is hard to help without the relevant code.
However, in your 3rd snippet, you are querying User - but I think your User schema is not correct.
I suggest that you separate Todos into its own Schema and export separately to User i.e:
module.exports = mongoose.model('Todo', todoSchema)
By passing dbname as options parameter you can specify the database,
check out the link for clarity.
https://mongoosejs.com/docs/connections.html#options

How to query imported json using Mongoose

I've uploaded a json file to MongoDB Atlas cluster (using mongoimport) and now I'm trying to display the data to localhost using express and mongoose.
I've gotten to a point where I can connect to the cluster but I'm struggling in fetching and displaying the data. Below is the code I have thus far. I'd like to query the database via Nodejs using mongoose as I do on the command line with Mongo shell. What am I missing here?
const express = require("express");
const mongoose = require("mongoose");
const app = express();
// DB config using Mongo Atlas
const uri = require("./config/keys").mongoURI;
// // Connect to Mongo
mongoose
.connect(uri, { useNewUrlParser: true })
.then(() => console.log("MongoDB Connected..."))
.catch(err => console.log(err));
// #route GET
app.get("/", (req, res) => res.send(db.restaurants.find()));
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Server started on port ${port}`));
First, initialize a model which Mongoose needs to query data. Since you've imported the data, you don't necessarily have to structure your schema.
// restaurants.js
const mongoose = require('mongoose');
const RestaurantsSchema = new mongoose.Schema({});
module.exports = mongoose.model('Restaurants', RestaurantsSchema)
Then, import the schema 'Restaurants' into your main driver file and specify your query by chaining filters like so:
// main.js
const express = require("express");
const mongoose = require("mongoose");
const Restaurants = require("./restaurants");
const app = express();
// DB config using Mongo Atlas
const uri = require("./config/keys").mongoURI;
// Connect to Mongo
mongoose
.connect(uri, { useNewUrlParser: true })
.then(() => console.log("MongoDB Connected..."))
.catch(err => console.log(err));
// #route GET
app.get("/", (req, res) => {
Restaurants.find()
.where("filter1").gt(200)
.where("filter2").equals("$$$")
.where("filter3").nin(["Coffee"])
.limit(100)
.sort("sort1")
.select("column1 column2 column3")
.then(restaurants => res.json(restaurants))
.catch(err => res.status(404).json({ success: false }));
});
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Server started on port ${port}`));
You should fill in the applicable values for "filter", "sort", "column", "gt", "equals", "limit", and "nin".
I am not sure if this is the only record of that type of json in your data base. But If you want to send if follwing a get request you first need to get the document.
// #route GET
app.get("/", (req, res) => res.send(db.restaurants.find()));
// may be something like
app.get('/', (req, res) => {
mongooseModel.find({query}, (err, result) => {
res.send(result);
});
})
Depending on what mongoose.model defenition you have and how you would like to find it you could use find (return an array) findById (return single document) or findOne and a query.
here an example how to create you model:
//restaurant.js
const mongoose = require('mongoose');
const RestaurantSchema = new mongoose.Schema({
name: { type: String, required: true },
address: { type: String, required: true },
description:{ type: String, required: true }
//just you add how you need your schema
});
module.exports = mongoose.model('Restaurant', RestaurantSchema);
and here your updated code
const express = require("express");
const mongoose = require("mongoose");
const Restaurant = require("./restaurant.js");
const app = express();
// DB config using Mongo Atlas
const uri = require("./config/keys").mongoURI;
// // Connect to Mongo
mongoose
.connect(uri, { useNewUrlParser: true })
.then(() => console.log("MongoDB Connected..."))
.catch(err => console.log(err));
// #route GET
app.get("/", (req, res) => {
Restaurant.find({}, (err, docs) => {
res.send(docs);
});
);
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Server started on port ${port}`));

Categories

Resources