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?
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I have recently begun exploring the concept of microservices and API gateways and am particularly confused on how frontend endpoints should be hosted.
If I have an API gateway that acts as the middleman between requests to all of my services, where exactly should the frontend be hosted? If I request /api/example, I understand that my API gateway should route that to the appropriate service and forward that services response. I do not understand however, how an API gateway should handle /home/ in a microservice context. In this case, we want to deliver html/css/javascript corresponding to /home/ to the client making the GET request. Does this mean that we should have some sort of frontend service? Won't creating a service that just returns HTML/CSS/JS be redundant and add increased latency, since all we really need to do is just immediately return the HTML/CSS/JS associated with our frontend?
An alternative I was thinking about was to have the API gateway itself provide endpoints that return the HTML/CSS/JS required for the client to render the frontend. In other words, the API gateway could just immediately respond with the HTML corresponding to /home/ when receiving a GET request to /home/ rather than calling a service. However, I read online that API gateways should not be actually serving endpoints, rather just proxying them to services.
That is my main question: Where should frontend code go when your backend is built out using a microservice architecture?
I assume your frontend is Single Page Application. SPA has static content like HTML, CSS, images, fonts etc. It is the perfect candidate to be deployed as static website that gets data from backend using REST APIs.
In cloud environments like AWS, GCP it is recommended to host SPA applications separately from REST APIs. e.g. in AWS SPA can be deployed in Amazon S3 and it remains directly accessible without going through API gateway.
API gateway is supposed to be used to only route REST API calls and performing cross cutting concerns such as authentication etc. However the problem with this approach is that you will get CORS error while hitting REST APIs from frontend because SPA and API gateway will be hosted on different domains. To overcome this issue CORS need to be enabled at API gateway.
If you are looking for simpler solution, frontend can be served from a service through API gateway. Since static content is served only once in SPA it should be okay to start with this approach for simpler applications.
https://aws.amazon.com/blogs/apn/how-to-integrate-rest-apis-with-single-page-apps-and-secure-them-using-auth0-part-1/
https://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteHosting.html
API Gateway as you have already mentioned should act as a proxy/router with minimal logic. And as the name says it all, its main purpose is to expose API and not GUI components/pages for different types of clients and address some of the non-functional aspects e.g. security. Provide high-level API [use case driven] based on requesting client[basically BFF/Backend for Frontend approach].
When it comes to having frontend/GUI fittin to microservices, you can think of having UI Gateway/Container which is backed by Micro FrontEnds. Also, refer to MF's site for details on micro frontends.
So, following microservices architecture for frontend, your frontend code should reside in micro frontends along with other microservices.
Before answering your question let me go through the different rendering strategies:
Traditional Server Side Rendering
Quite uncommon nowadays. You don't need any API gateway, since everything is computed and rendered in the server you can perform the necessary calls to other microservices there.
Pros: simplicity; instant interactivity for the user on page load; SEO
Cons: full reloads each time
Client Side Rendering
Most popular option in the last years. You provide a basic static HTML/CSS/JS bundle, perform requests to an API to retrieve some data and use some sort of template engine to render new pages and components.
Pros: no full reload; lazy loading; richer interactions; benefits from CDN
Cons: SEO; page not interactive on load; slower first load
Since the rendering happens in the browser you don't need to serve the static HTML/CSS/JS files from your server. Instead, you should use a CDN to deliver them faster.
The other requests to non-static resources will be performed against the API gateway, which is responsible to forward the request to other services (or make some sort of orchestration/aggregation).
Modern Server Side Rendering
This is gaining traction nowadays thanks to frameworks like Next.js. The page is initially rendered in the server using the same template engine that it's going to be used in the browser, so you can send an interactive page faster while keeping the features and benefits of client side rendering.
In this case all the static pages can be pre-rendered, cached and served through a CDN. For dynamic pages you can still send a partially cached/rendered page that will later fetch the additional necessary information from the API gateway.
TL;DR: You don't need to serve your static HTML/CSS/JS from your API gateway or your server. You should deliver them through a CDN to improve loading times.
Otherwise the static files shouldn't be served through the API gateway, IMHO. You could make your /api/{resource} requests go through it and forward all /{page} requests to static resources.
Using API responses for a Frontend app, does not make sense if you are returning the WHOLE body of the Frontend, as you point out.
However, you can load (initially) a frontend, that contains let's say header, with a menu, footer, and a main body section with few elements, like articles.
Upon interacting with this frontend, an action can be triggered to that API (usually via JS Ajax calls), which will request specific portions of new data from the API, and once received, the JS will update only the relevant portions on the webpage, and not reload or replace (or refresh) the WHOLE page.
This if done correctly can save a great deal of network traffic, thus making the website more flexible, without it being fully reloaded every time you need new data to visualize.
One simple example:
When you click on a link in your menu, to load a contact form, the API will return either the raw HTML for only the contact form, or it will return (usually) a JSON object/array, that will be used to further generate/replace a portion of your main body, to BECOME now the contact form..
Where exactly should the frontend be hosted?
Where should frontend code go when your backend is built out using a
microservice architecture?
Your Front-end (web) application usually sits BEFORE the API Gateway. Requests to resources like HTML/CSS/JS are served right from the Front-end application itself, hence no API-Gateway involvement here whatsoever. If the page contains an (AJAX) call to a back-end (Micro)service, it might (should) go through the API Gateway. From hosting perspective, they are hosted as a separate web application.
how an API gateway should handle /home/ in a microservice context?
It won't (i.e not intercepted by API Gateway at all). Requests like /home are page requests served directly by Front-end application itself (Of course, it will have its own scaling mechanisms like Clustering, Caching etc)
I wish to make a progressive web app for a domain www.xyz.com and another progressive web app for the domain www.xyz.com/abc. How should I go about it and what will be the behaviour of service workers in both the cases? Will there be 2 service worker registrations or a single one will work for both the PWAs? Also, should I make 2 manifest files for them?
You can have only one PWA for both URLs. When you create your service worker, its scope covers the current folders and the relative children.
If you place it at the root level, you can use one service worker for both URLs, without the need to make thinks more complex introducing nested constructions.
You can define different caching strategies within the same service worker with ease.
If you want to deepen the PWA topic, you can have a look at the articles I wrote about them, starting from basic concepts and then going deeper with more advanced themes.
Update
The scope property of the manifest file determines which HTTP calls can be intercepted by the Service Worker (SW).
If you have scope: '/', your SW will intercept all HTTP requests made by your app. If it would be /user, the SW couldn't intercept a request that doesn't fall within its scope (e.g. /orders/code.js), but it would intercept all GET calls under the user root, like /user/details.
In your case you can have therefore two SWs (even on the same page) where you can define different scopes to intercept, you have just to be careful in not overlapping the scopes among them.
If you plan to cache also static assets, keep it in mind that the scope for the SW is given by the folder where the SW file is stored and its subfolders.
About multiple manifest files, Jeff gave an answer about it on SO.
Working on a new project, I need to create two sets of the front end with a same back-end code base and data. The second set of front end can be accessed through a sub-domain name such as secondfrontend.mywebsite.com. What will be the best approach between two sets of front end codes and two basic pages of the single page applications? I am going to use Vue for the front end as it is the simplest Javascript framework in the current JHispter project.
You can consume the JHipster REST API from any consumer you want (SPA, native mobile, ...). Since you have 2 webapps and not written in Angular, you would probably serve them from another http server than the Spring Boot app as static contents (lots of solutions there depending on your infra. Eg: Apache/Nginx, CloudFront, Express, ...). Note : If the fronts and the back are not on the same domain, you will have to take care of setting the CORS accordingly in the Jhipster app.
Also note that JHipster does a lot of optimizations when serving the static content (gzip, set caching headers, ...) so you will have to reproduce these optimizations in your server if you want optimal performance.
For this kind of expansion, I would definitely use a REST API with some sort of load balancing/caching sitting just before the entry point of backend. For sub domain, Cross Site Origin (CORS) should be able to take care of your problem.
Although, I have never used JHipster, but Spring with RestController that serve as rest API is a very nice option if you are working with very large backend. Just bare in mind that Spring Security takes in a urlencoded HTTP Body (Although through some Added filter JSON can also be parse in).
Vue as a front end is also a very nice option for SPA.
I'm working with Yii Framework 2. How can I create an app with one backend and two front ends?
For example:
Backend for Admins and Moderators (url: admin.example.com)
Frontend app for Publishers (url: publisher.example.com)
Frontend app for Advertisers (url: advertiser.example.com)
All apps should have a common db, models and 3 different layouts.
I found a Yii2 advanced template where are only two: frontend and backend.
You can build as many fronts as you need by adding them as independent modules. Each within a separate folder, with its own configs and own controllers. Then they may all share the same models.
You may check Module docs for more details or you may also check this example which is built for REST on top of a basic template, so you'll need different apache and app configs but it is practically the same.