Deploy a React app + Node server with Heroku - node.js

I want to deploy a project (React app + Node server), but I'm new to deployment,
I wanted to know : do I need to have the React app in a Github repo and the Node server in another, or I can deploy all in one ?
Currently, I have 1 Github repository with a folder "frontend" and an other "backend",
I want to have my React app on -> nameofmyapp.herokuapp.com
and the Node server on -> api-nameofmyapp.herokuapp.com,
If someone got ideas... Thanks

While in theory that's not a problem, I would suggest maybe considering keeping things on one domian for reasons such as additional latency and connection trouble as well as path issues such as you are facing. It would seem to me that you would ideally just like to prefix the name of your app with 'backend' or similar and in such a case I would just consider setting up a sub domain on a domain which I had control ie mydomain.com and backend.mydomain.com. While developing on Heroku this model could prove to be tricky as each 'site' or app is separate and not actually intended to work together while they most certainly could. Consider setting up separate routes and an endpoint for 'backend' on your app, similar to your frontend login, then when you are finished developing your app and happy you could register your domain name and point it to your app and point a subdomain ie backend.mysite.com or login.mysite.com to your endpoint on Heroku ie mysite.com/backend. Unless you have a specific reason for separating them into their own repos with separate source control and urls, it might make debugging things much harder. Apologies if I missed your point. Most web hosting companies should allow you to register a subdomain or vanity domian free or charge because you own the primary domian. Just some considerations.

Anything is possible, you just need to understand how things are working... my advice would be that you start simple and have a single repo that contains front+back, you can then deploy that as a single Heroku app.
One app can only have a unique Heroku url, so you cannot have what you mention nameofmyapp + api-nameofmyapp hosted by a single Heroku instance, this would need to be hosted by two different instances, which means code from two repos.
Usually for a node app, you would create an /api route that is hosted by the same app, so you have your frontend served at nameofmyapp.herokuapp.com and your api at nameofmyapp.herokuapp.com/api with some sub routes, for example nameofmyapp.herokuapp.com/api/items.
You should be able to easily find tons of Node/React/Heroku tutorials on the web, just play a bit with it to experiment and build some understanding of how those are working together.

Related

Unable to deploy a node.js / vue.js SPA online

I'm working on a project for adding an external pre-registration page with Stripe to a Wordpress website.
The wordpress is already in place. But the pre-registration page needed the Stripe module, working on back-end...
So I've decided to make a SPA outside this wordpress to have this pre-registrations set up for the next customers.
But now, I'm struggling from days to find how to put this project online, I may definitely need your help for that.
I have this file structure:
File structure
It's nothing more than a single page + a single css file and a single server.js file, that I need to start to interact with the Stripe API.
But I also need some modules like Stripe, which is the key function of this project.
I thought about bundling it with webpack (only the back-end, as the front is only composed of 1 html and 1 css file). Then upload it on my web host.
Haven't found any working way to do so.
I'd like to try some cloud services like Netlify, but I don't even think that it could work without bundling the server side
Everything works perfectly on localhost, but I'm absolutely unable to make it works in prod with a real domain name. And I'm already late to deliver it.
Do you have an idea on how I could do that?
Thanks

Running server and react app from one place

I'm trying to set up a server and react app to both serve from one place, and host from one domain. This gives me the advantage of one repo and being able to use server side cookies instead of auth tokens.
See also this link: https://dev.to/nburgess/creating-a-react-app-with-react-router-and-an-express-backend-33l3
I also prefer to use typescript.
I really think this would be a good approach, but it is hard to find resources. All courses, free or paid, are working with separate React / Angular frontends, which then need to fetch data from a backend on a separate domain.
Does anyone know a good resource how to combine a react frontend and an express backend and host it from one place? Or are there good reasons not to do that, which I just don't see at the moment?

Google App Engine API + static architecture

I'm trying to (con)figure the best way to structure a JS client + NodeJS server app to host it on Google Cloud AppEngine (plus possibly other GCP resources). So I'm looking for advice / best practices here.
We have an API server running on a non-default AppEngine service and would like to be able to run several, e.g. development/staging/production versions on the same project (if possible).
We would like to host / serve our static client app on this system because we want to use the same domain to point at it.
In our normal server based setup, the client app is proxied/served on domain.com/ and requests to the API are on domain.com/v1/
I've been working through different options - hosting a separate static site running on AppEngine and using dispatch.yaml to try to route requests - this option doesn't seem to work with domain prefixes, only wildcards, e.g.
dispatch:
- url: "my-client-service-project.appspot.com/"
service: my-client-service
- url: "my-client-service-project.appspot.com/v1/*"
service: my-backend-service
Doesn't work, but:
- url: "*/v1/*"
service: my-backend-service
Does, which we didn't want because we'd like to run dev, staging & production if possible.
The other option I've been looking at is having the static folder hosted as part of my app, but I can't seem to get this working either, here is the snippet from my app.yaml:
handlers:
- url: /.*
static_files: client/dist/index.html
upload: frontend/dist/index.html
- url: /v1/*
script: dist/index.js
My guess is that script may not work the same as for Python apps, but I could be wrong - the doc's aren't very clear.
Ideally, I'd like to host the client front-end static files on storage and point to the AppEngine API server (without specifically pointing to a domain from the client, e.g. /v1/auth/login rather than my-backend-service-project.appspot.com/v1/
References:
How can I use bucket storage to serve static files on google flex/app engine environment?
Node.js + static content served by Google App Engine
https://cloud.google.com/appengine/docs/flexible/nodejs/serving-static-files
https://cloud.google.com/appengine/docs/standard/python/how-requests-are-routed#routing_via_url
https://cloud.google.com/appengine/docs/standard/python/config/appref
https://cloud.google.com/appengine/docs/standard/python/config/dispatchref
To begin: you're mixing up standard and flexible env docs - not a good idea as they don't work the same way. See How to tell if a Google App Engine documentation page applies to the standard or the flexible environment.
Since your app is Node.JS you have to use the flexible env, for which script and static_files aren't applicable inside app.yaml. Which is why you can't get them to work.
The first reference in your list shows the options you have for serving the static files. But I kinda question your desire to use the shared GCS option - it will serve the same content regardless of the dev/staging/production environment, so:
you can't have different client side environments
how do you see selecting a particular server-side environment since the client side references can only point in one direction (i.e. environment, if I understand your intention correctly)?
If your desire to use a single domain means that you'd still be OK with using different subdomains (of that domain) and if you'd be willing to use a custom domain this might be of interest: How to use GAE's dispatch.yaml with multiple development environments?
UPDATE:
Node.JS is currently available in the standard environment as well, so you can use those features, see:
Now, you can deploy your Node.js app to App Engine standard environment
Google App Engine Node.js Standard Environment Documentation
Take this answer as a complement to the one of #Dan Corneliscu, as I think it is pretty useful and summarizes what you are doing wrong and what can be achieved in the type of scenario you present. In any case, I would like to provide some more information which may be useful.
As for the reason why the dispatch rules approach you suggested does not work, you should update your paths in the application accordingly. They should now be listening to /v1/your_endpoint instead of /your_endpoint as they probably did before. It is not enough with changing your dispatch file. Then also make sure that the Dispatch routes field is populated in your App Engine > Services tab in the Console.
Also the alternative approach you suggested will indeed not work using static_files, but you can follow this guide explaining how to serve Static Files from a GAE Flexible application.

Vuejs frontend served by Express and backend API in node security practice

I am currently working on a small project where I used vue.js to build the front end and express.js for the backend.
For the frontend, I have another express server to just serve the static files and all the requests will be redirected to my backend API with proxy by the frontend server.
For the backend, it is just an Express API app.
Both apps are runing on heroku right now. And my questions is:
What is the best practice to connect the front end and back end server, I did a lot of research online and people are saying backend API are not supposed to be exposed to internet? I am not sure how I can talk to my backend if it is not on internet.
For the frontend, I can use SSL/TLS to protect the connection. But for frontend to backend server communication, what should I do to protect this data transfer, can I use another SSL/TLS? And should I use some mechanism to verify that the request is sent from my frontend server, not somewhere else? If so, what is the recommanded way to do that?
A lot people say that there should not be direct connection with database, it should go through a web service for security. What does that means? Now in my backend Express app, I have line of mongoose.connect('mongodb://someaddress/myapp'); Is this bad practice? If so, what should I do to make it more secure?
Please try to be more specific, I am still new to theses and try to learn, code examples can really help. Much appreciated!!
Vue and Express apps are written in the same language, so it is best practice to have these as separate projects as you have done. These are entirely different projects doing different things so they should be split.
You already deployed to Heroku, so the SSL/TLS isn't really a concern for you. However if you were deploying to your own VPS, you'd want something like Let's Encrypt. For restricting requests from Express to your Vue app, you'll want to look into CORS. See expressjs/cors for more details.
The Express app is the service connecting to your database. If you were trying to directly connect to your database from your Vue app, then that becomes an issue. You would coupling client side code with server side code. What you're doing is fine.

How to integrate a Nodejs API with ReactJs app under the same domain

I'm trying to understand how a MERN app fully works, I've been reading about MongoDB, ExpressJs, ReactJs and NodeJs, I also understand how MongoDB, ExpressJs and NodeJs interact and how ReactJs works on its own, my question is simple (I think).
The question:
If I create an API, using Node,Express and Mongo, and I have an APP managed by React, both need a server (via express, I understand), then, how should I run the API and the React app at the same time. Do I need different URLs? should I configure different ports? how should I integrate them?
I really been reading a lot, but almost every tutorial is made locally (and I'm working in a server with Passenger and I can't change the way it starts), just for Node/Express(with pug or else)/Mongo or just React, and I don't understand how to connect the API and React.
Thanks
It depends on several factors: environment (e.g. development, production), and your control over the server. For development, you can have two different URLs and use something like Webpack Dev Server. Normally you would have the module bundler, e.g. Webpack, watching for changes in your React code. However, this can get more complex if you have Server Side Rendering.
For production, normally you would have the bundled file for your client side application already optimized and minified. If you can change your API, you could serve it statically in a new endpoint, for example: /static/bundle.js and request this endpoint from your index.html file, which will be sent by Express.js server when accessing /.
However, because you will probably want to have routes in your React app, your server will need to know how to handle the client app routes (for example app.get('/*', () => ...), and they could collide with your API endpoints. To solve this, you could:
Prefix your API endpoints with a namespace, e.g. /api/v1/...
Place the API in a different URL, port or subdomain. In this case you would indeed need to run these two servers in parallel. With Node.js, there are helpers to make this more convenient, e.g. concurrently.
Pulling out your concerns: API, React, and Integration for MERN app.
I use three approaches
1) Use foreman. With this, you can specify your API and Web Client in the Procfile. I used it here
2) Use a proxy to handle requests that require your API. So in package.json, you specify your API URL(your API must be running)
// package.json
.......
.......
"proxy": "<path to url:[port no if you're developing locally]>"
Check here.
And you can simply add a script to run your API and React concurrently.
3) Set your API and React app in a Docker container. mern-starter is a perfect place to check for this.
Hope this helps!

Resources