I'm fairly new to the webdev. I have a React frontend built with Vite, and a Node.js backend that uses MongoDB. I finished my little project and when It came to deploy it to my Linux server, I got confused about how to handle API calls.
Is there any way to hide API URL's on frontend apps? Because everything is done in client side, and frontend is basically an interface between user and backend, that should be impossible. But how does for example, big companies like Facebook handle this? If I go to Facebook and inspect the code, can I find the exact IP and API address that facebook backend serves me the posts? Or are there any tricks to make this more secure? What are the industry standards are on this topic?
The interface between your web application in the browser and your backend service is HTTP(s). There are HTTP verbs such as GET, POST, DELETE, etc. You can pass argument or information to your backend services via query parameters which are visible in the URL, or you can send it in the body of a request. An HTTP POST, for example would have a body that is not seen or viewable unless the end user made specific effort to view it.
We are migrating our application from app.site.com, which used to handle all requests, front, back, API etc. to a new setup where app.site.com is a static react site served on s3, and api.site.com now handles all our our API requests.
We however have some old devices out there that will still send API requests to app.site.com/api with some post data.
Since app.site.com/api no longer handles these requests, but api.site.com/api does, is there any way we can forward or redirect these old requests on app.site.com/api to our new API service? It seems like we may be stuck since app.site.com is a static react site now.
We run on AWS. I was wondering if this might be possible with an application load balancer or maybe there is some other idea I'm not thinking of.
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)
My problem is as follows :
I'm developping a web application with Angular. Angular application runs on the client's browser. In its logic, my application needs data from other-domain.com.
I can't use directly XMLHttpRequest() because of CORS policy problems. (The web server other-domain.com producing data is not my domain and cannot add 'Control-Access-Allow-Origins')
So instead of having :
Angular ===>> other-domain.com (forbidden because of CORS)
I'm creating a REST API that will get data from other-domain.com and wraps this data with header 'Access-Control-Allow-Origin' : '*' before sending to client's Angular.
So my workflow becomes :
Angular ==>> my API server ==>> other-domain.com (allowed because request for other-domain does not execute on the browser)
Do you think my idea works well forevery request (GET, POST, adding cookies header) ? In that case the API I'm developping acts as a proxy, right ?
Thank you
Short answer: yes. In fact, there's packages and sites out there that will do this for you.
But I think another question is why you have the need to circumvent CORS restrictions. After all, it is working as intended and there's a reason for its existence in the first place.
If you have a backend already, can you add an endpoint where your backend will make the call to the other domain, and leave the browser to communicate only within your domain?
If you're only doing RESTful GETs and an opaque request (no credentials, no cookies, etc.) will suit your needs, you could also just use the fetch api with {mode: 'no-cors'}; however, you'd need to 'circumvent' the HttpClient to do so and you'd need a polyfill if you need to support IE.
I have server with node.js + express for routing. When I do requests like http://mydomain.com/photos, http://mydomain.com/photos/123, etc I got JSON answer. This is OK and exactly what I need. So RESTful API is ready. But this is just data and I need also to process this data and show it as webUI (html, css, angularjs).
How to implement webUI for this purpose properly?
I need to have unique independent server API in order to use it for different clients: browser web site, mobile apps, etc.
You probably want something like the MEAN stack: MongoDB + Express + AngularJS + NodeJS.
Your client (AngularJS) is being delivered somehow (static hosting, express, cdn, nginx, etc) and then performs REST requests to an external server (Rails, Express, Php, etc) that has CORS enabled if lives in a different domain. This structure is known as Single Page Applications (SPA), where a single big HTTP request is loaded in order to interact with a backend.
That being said, this is nothing new... things like CouchDB, SammyJS and so on had been working on this for a couple years now.