Backend API fetch, instead of React - node.js

I'm new to programming and created a weather app to practice React. I also created a Node server and a homepage (portfolio). So my tree look like this:
project
-portfolio(homepage with simple html file)
-weather(React)
-server.js
Inside the weather app I make a couple of API fetches to openweathermap.org. But it has come to my attention that my API key will be visible when I publish this app and that the best way to avoid that, is to make the call in the Node backend. How do I move data from the weather app to the server.js and vice versa? For example, the user will enter a zip code in the weather app. This zip code is used in the url to fetch the data. How would I make the zip code show up in the server? And then do I just perform all the fetches in the server?
My weather app code can be found at this previous question. I did make the modification suggested and now have two separate useEffect. React - API fetches - 2nd fetch uses data from 1st fetch?
Thank you for your help.
server.js
const express = require("express")
const app = express()
const path = require("path")
const port = process.env.PORT || 5000
app.use("/weather",express.static(path.join("weather/build")))
app.use("/",express.static(path.join("portfolio")))
app.listen(port, () => console.log("Working"))

If you're using API keys on your frontend, it will always be exposed to anyone who checks your network requests. If you insist on using the API key with frontend requests, you should atleast use the .env module in your React frontend and add your API keys there, making sure you commit your .env to your .gitignore so it won't get committed to your source code.
const port = process.env.PORT || 5000
I'm assuming you already know how to set this up since you're using it here.
OR
You could just reverse proxy your request with your API endpoint, store your API keys in your .env, and have your route make the API request to openweathermap.org-- successfully hiding your API keys from network analysis:
React Weather App => YOUR_API_ENDPOINT
YOUR_API_ENDPOINT =>
openweathermap.org
Parse data => Send response to Weather App
How do I move data from the weather app to the server.js and vice
versa? For example, the user will enter a zip code in the weather app.
This zip code is used in the url to fetch the data. How would I make
the zip code show up in the server? And then do I just perform all the
fetches in the server?
Pass it as a param in the url of the request and have your backend parse out the params from the url.
Weather App:
axios.get(`${YOUR_API_ENDPOINT}/zip/${DYNAMIC_ZIP_CODE_DATA}`) //basic example
Node
app.get("/zip/:zip", (req, res) => {
console.log('params: ', req.params.zip)
const zip = req.params.zip;
//make the API request here and pass in the zip
res.send(req.params)
})

Related

get data from webhook telegram bot with node js

I set the server address for the bot with /setwebhook, now how can I get the data with only node js and https package to access {message :{...} }? (like /getupdates method) but by webhook , probably I mean like the php code but in node js: file_get_contents("php://input") .
Should I use async or https.createServer ? If yes, how and please explain a little
You have to create a server that will handle receiving the data. You can do this by using http.createServer or, more conveniently, using a library such as Express. Simple implementation using Express would look like this:
const app = express();
app.post(`/api/telegram${process.env.TELEGRAM_BOT_TOKEN}`, async (req, res) => {
const message = req.body.message || req.body.edited_message;
...
});
In this example, I use bot token in the webhook url (since I and Telegram are the only entities that know the bot token, I can be sure that the requests to the url come from Telegram). There are better ways to make the webhook secure, such as using secret_token as specified in the docs for setWebhook method.
For development purposes, you can use a service like ngrok to redirect requests from the bot webhook to localhost.
To get an idea of a fully functioning example of implementing webhook with node.js and Express, you can check my open-source project on Github.

Is it possible to host web page with angular.min.js functionality using nodes http module

Is it possible to host web page with angular.min.js functionality using nodes http module?
I'm making a really simple web project that is going to fetch some data and I decided to use angular.js to display data no the page. I tried to read index.html using fs module and sent it as response to the localhost. It seems that angular.min.js, that was included in the pages head section did not load as it would when I run the page in the browser from the file explorer.
angular is a web application, so, please serve the angular using your node.js server and load the app in the web browser.
add a listener of get then send all files that index.html need, it is done.
or use app.use(express.static('public')); which public is your 'public' folder, put all file in dist to serve as a static content.
I use the first option every time but it is trick but functional.
sample code is:
const express = require('express');
const router = express.Router();
const path = require('path');
router.get('/:id',(req,res)=>{res.sendFile(path.join('/path/to your/file/'+req.params.id));});
router.get('/',(req,res)=> res.sendFile(path.join('/path/to/your/file/index.html'));});
module.exports = router;

How to create a node based server to serve REST API and also deploy the application.

I am new to nodeJS server area, need help in understanding how to work with REST API (using express) and deploy the angular application over a singe node server and same ports.
By deploying i want to understand if user hit below url http://localhost:8000/<page_name> then the specified page should open.
And is user hit below url using get or post request
http://localhost:8000/api/<api_name> then a json or a text will be returned.
How to run both the thing over a single node server.
Lets assume, you have all your static files in the /public folder of you app. Generally spoken, if you are using express.static, you should also get your index.html because this is handled by default for each directory.
In your case, as you are using Angular, the routing is handled from the client side (SPA). You should only have one single index.html after building your Angular app. All files from your dist folder should then be placed into your /public folder. Then you need to make sure, that initial file serving provides your index.html like so:
In this example static files are served first, then your API and if nothing is found, you are getting back you index file.
const express = require('express');
const app = express();
// serve static files
app.static(__dirname + '/public'));
// serve your API
app.get('/api/welcome', function (req, res) {
res.send('Welcome');
});
// fallback routing (server side handling)
app.get(/.*/, function (req, res) {
res.sendFile(__dirname + ‘/public/index.html‘
});
app.listen(3000);
Next time please make sure, to give all necessary information in your question ;-)
With the help from Sebastian, so far I can find a solution but its not working when i am hitting URL for different pages.
const express = require('express');
const app = express();
app.use(express.static('public'))
Please provide your suggestions.

Connecting frontend and backend MERN stack

How does the react client connect to the server via express? Many tutorials talk about Superagent and axios which is adding to my confusion. Are there any resources on server side routing in the context of react? thank you
In MERN stack, you do not necessarily have to think of the entire stack as a single entity. Mongo, ReactJS and NodeJS server can all work independently. And let us for easiness of understanding sake say all of them are on separate servers. That is we can have Mongo on one server, ReactJS on another server and NodeJS with express on a third server, then also it will be a MERN stack app.
How a MERN app work is as follows
For example, let us have an app that displays the details of all the students in a class. First, in the React app let us say you select a class, and then the React front-end will send a query to the nodejs server. The query will contain the particular class name. Now nodejs will send a query to the mongo db asking for the details of the students of that class which it will send back to the node server. The node server will then send the details to the front end and it will update it.
If you ask for connection as such, there can be no connection at all except for querying for data. Instead of using the reactjs front end you can use some other frontend and it will give you the same details. React, Mongo and Node, all are capable of working on their own in their respective fields.
Axios is a promise based HTTP client for the browser and node.js.
They are completely independent. Whether using axios, the native Javascript fetch, jQuery AJAX, etc...each of them runs in the browser and makes a GET/POST request to nodejs. You will have defined corresponding GET/POST routes within nodejs to respond to these requests and return JSON response data for them to consume.
I would start by forgetting about react altogether. Instead build an express API with various GET/POST routes that return JSON responses. Test with a simple client like postman. Once you have a handle on that, then start with a front-end Javascript framework to consume these services.
Here is a cut of my express+react api:
var express = require('express');
var router = express.Router();
router.get('/', function (req, res) {
res.render('index', {myjson: "myValue"});
})
module.exports = router;
Basically I am sending the json string to index.jsx, where the frontend is rendered.
Also I've set in express as:
app.set('views', __dirname + '/views');
app.set('view engine', 'jsx');
app.engine('jsx', reactViews.createEngine());
So the express server knows where React is.
Checkout the npm package Express-react-engine.
All the elements of the stack can be used independently, React , Node.Js, and MongoDB.
They can be installed in different servers and the communication is by using Fetch, Axios or any other tool.

create-react-app with Express

I need to query a database and I'm using create-react-app. The library to connect to the DB (pg-promise) does not work with Webpack and needs to be running on a Node server.
So I installed Express and have this:
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, '..', 'build', 'index.html'));
})
How can I load data from the database from the React pages? I though of using request but how can I make a request to my own server? And what should I add to the lines of code above? I think it would be something like:
app.get('/query/:querybody', (req, res) => {
// process and return query
})
Is this right? How can I make it work with a SPA?
Probably the most friction-free method would be to have a separate app.js or server.js along side your CRA application. You can use a tool like concurrently to run both your React app and the express app.
The trick is to serve your express app on a different port than the default :8080 that CRA serves on. Usually 8081 is a good choice, as it's a common convention to use port numbers that are close together when developing.
In your React app, you will need to make sure you use the full URL for the express endpoint: http://localhost:8081/query/...
On the server side you are going in the correct direction: you need to setup endpoint which will respond with data based on request. In you example you setup an endpoint for a GET HTTP request. If you will need to pass a complex request (for example add new record to database), consider using POST HTTP requests.
On the client side (in the browser) you will need a library that will assist you in sending requests to your server. I can recommend to try Axios (https://github.com/mzabriskie/axios). Usually if you omit protocol, server name and port, request will be sent to the server from which the page was loaded:
http:127.0.0.1:8001/api/endpoint => /api/endpoint

Resources