we are currently facing some tough architectural questions about integrating multiple Web Components with individual backend services in a composite web UI to one smooth web application.
There are some constraints an (negotiable) design decisions:
A MicroService should serve it's own frontend (WebComponent), we would like to use HTML Imports to allow including such a WebComponent to the composite UI
A frontend WebComponent needs to be able to recieve live updates/events from it's backend MicroService
The page (sum of Web Components used in the composite UI) shall only use one connection/permanent occupied port to communicate with the backend
I made a sketch representing our abstract / non-technical requirements for further discussion:
As of my understanding, the problem could be rephrased to: How do we
a) concentrate communication on entering
b) distribute communication on exiting
the single transport path on both ends.
This two tasks need to be solved on both sides of the transport path, eg. the backend and the frontend.
For the backend, I am quite hopefull that adopting the BFF pattern as not only described by Sam Newman could serve our needs. The right half (backend) side of the above sketch could then look similar to this:
The transport path might be best served using standardized web technologies, eg. https and websocket (wss) for the most times needed, bidirectional communication. I'm keen to learn about alternatives with an equivalent high adoption rate in the web technology sector.
For the frontend we are currently lacking ideas and knowledge about previously described patterns or frameworks.
The tricky thing is, that multiple basically independent WebComponents need to find together for using the ONE central communication path. If the frontend would be realized by implementing one (big) Angular application for example, we would implement and inject a "BackendConnectorService" (Name to be discussed) and inject in to our various components.
But since we would like to use decoupled Web Components, none such background layer for shared business logic and dependency injection exists. Should we write a proprietary JS-library, which will be loaded to the window-context if not present yet from every of our components, and will be used (by convention) to communicate with the backend?
This would roughly integrate to the sketch like below:
Are we thinking/designing our application wrong?
I'm thankful for every reasonable idea or hint for a proven pattern/framework.
Also your view on the problem and the architecture might be helpful to circumnavigate the issues we are facing right now.
I would go with same approach you are using on the backend for the frontend.
Create an HTTP or WS gateway, that frontend components will poll with requests. It will connect to backend BFF and there you solved all your problems. Anytime you want to swap your components, transfer or architecture, one is not dependent on the other.
Related
When doing microservices it's quite a common and good practice to have a top layer called API-Gateway, that sits in front of a group of microservices, to facilitate requests and delivery of data and services.
When using MicroFrontends to compose an UI app from multiple sub-apps (MFE), I cannot really see a benefit about still using an API gateway to communicate between each MFE and its corresponding Microservice.
In many schemas, an API-Gateway is still used in front of the microservices
Example here :
But the fact that each microfrontend is its own app also probably means it will communicate with its own API. In this case I would either use a thin API layer over each microservice, and then make each MFE communicate directly with this layer, because a MFE probably won't ever need to read data from another MFE (this would go against the spirit of MFE, or am I wrong ?).
What kind of approach would you use in your projects ?
When reading literature about microfrontends, I always see that the frontend is composed of microfrontends that different teams develop. Each microfrontend has at least one backend. What I do not see is that the backends communicate with each other. Is that right? Are they that way separated that they can completely live with out any communication between the backends?
Benefits of microfrontends:
Ability to deploy UI code independently between teams/domains
Ability to use different technologies per team
Hard boundaries/encapsulation of UI code for that domain
Faster build, test, deploy times given smaller codebase
Optimal microfrontend architecture:
Assuming a single user facing webapp:
A "platform" microfrontend serves the "skeleton" page
From the user's perspective, it's a single site with one domain name (avoids CORS issues)
The "skeleton" page calls out to team specific frontends, based on namespaced routes, typically this path-based routing is handled via an ingress or reverse proxy (e.g. /namespace/accounting goes to the accounting frontend)
Frontend service (microfrontend) is strictly responsible for presentation issues, and often calls out to other backend services that have ownership over various data.
Frontend service contains logic for both serving static assets/components, and for handling ajax requests/composing UI specific data.
Summary:
Your frontend service will generally have to call out to backend services to compose data for presentational purposes. For example, if you need to display user data, you will likely need to call out to some UserService or AccountService to get additional details about that user. I don't recommend attempting to build a separate datastore with replicated data that's specific to the frontend service.
The frontend service typically shouldn't contain business logic; however, there's an argument to be made that for smaller apps/earlier on it can make sense to have a single service that handles both the UI and business logic for the same domain. It's generally the lesser evil to have services that are too broad rather than too narrow.
However, in a microservices architecture it's still important that you keep necessary dependencies between services to a minimum. A common problem is running into "dependency" hell, where you call Service A, which needs to call Service B and so on, which makes the architecture slow and brittle. A frontend service would typically make calls to services that are only "one layer deep", and then compose those responses into a single display data/payload.
Finally, it's very important that you choose the boundaries of your frontend service/domain wisely. It shouldn't be the case that you have many frontend services that all need to frequently call out to the same backend services. Better to start with a single broad frontend service and break it down further as you become more confident in the boundaries.
After coding for a couple of years, I have implemented many different software services into applications I was coding, using API documentation that software owner has provided. And I thought that was all about APIs I need to know, that it's just a way to make to software services communicate with each other.
But now I got a task to create an application, I wont go into detail, but let's say it just needs to implement CRUD operations and that it should use Vue on front and Laravel on back. And in the explanation of a task it is mentioned that I should use REST API for triggering those operations. And that's the part that confuses me!
Since I have never created an application from scratch, I was only working on already stable applications, fixing bugs and implementing new functionalities (and I guess this is the what it looks like for the most of the people who work in big companies today), and that's why I thought that those two frameworks (Vue and Laravel) have already implemented REST APIs since they can communicate between themselves.
Why am I specifically asked to use REST API to trigger those operations? Is there any way other than using an API to make front communicate with back (even I am using frameworks already)? If not, do they want me to create my REST API for communication and not use the one that is already provided by frameworks? I am confused, why did they mention to use REST API as if it wasn't default option, something that shouldn't even even be questionable, just an expected behavior.
why did they mention to use REST API as if it wasn't default option
For many years, offering an API in the backend for JS frontend consumption was not the default option. Traditional "round trip" applications use a form that submits to the server with a full page refresh, and I'd hazard a guess that most web applications live today still work like that.
With the advent of Vue, React, Angular etc, there is an expectation that fetching data and sending data is done via APIs in an AJAX operation. This gives applications a more seamless feel, and they're faster, since only a relatively small amount of data needs to be sent or received.
In small Laravel/Vue applications, the frontend and backend are often in the same repo, and are deployed together as a single unit. However, as the size and complexity of an application increases, there is value in splitting up these pieces into microservices, which can be deployed separately, without tricky system dependencies complicating the deployment pipeline and sign-off process. Using an API lends itself well to that approach.
Indeed, as the backend increases, the API is not one service, but several, split by process area (e.g. user, sign-up, checkout, dashboard, etc).
Do Laravel and Vue always use ... APIs to communicate?
So, to answer your main question, you don't have to use APIs/AJAX with Vue and Laravel. You can still use standard HTTP forms and redraw the whole screen if you want.
Do Laravel and Vue always use RESTful APIs to communicate? [my emphasis]
Another way of interpreting the question is that perhaps you have received instructions from someone who was differentiating a REST API from a different kind of API. On the web, GraphQL is becoming more popular. Server-to-server, SOAP (XML) used to be very common, and is still in use in many enterprises.
FOA, The gap is not going to fill "ASAP" because it requires domain knowledge that you are missing. And yes RESTful API is the best way unless you want multi-dimensional communication across multiple platforms.
I'm working on a project that has multiple microservices behind a API Gateway and some of them expose WebSockets API.
The WebApp needs to be able to interact with those APIs.
.
Those WebSocket API can be built with frameworks that have their own protocols, using socket.io or not etc.
The main goal of this reflexion is to be able to scale and keep flexibility on my WebSockets APIs implementation.
I thought about two solutions :
The first one is to simply proxy requests on the gateway, the webapp will have to open a websocket for each microservice, this looks like a design flaw to me.
The other one is to create a "Notifier Service" that will be a WebSocket Server and that will keep outgoing connections with users and be able to bridge the incomming messages and outgoing ones based on a custom protocol. The drawback is that i need to implement a pub/sub system (or find a solution for). I didn't dig a lot into it but it looks like a lot of work and a homemade solution, i'm not a fan of it.
I didn't find articles that give feedback after exposing such an architecture and websockets in production, i was hoping to find some here.
I agree with you that a simple proxy solution seems to be inadequate as it exposes the internal interfaces to the clients. I found two articles which I think are addressing your problem:
The API Gateway Pattern
Pattern: API Gateway / Backends for Frontends
Both talk about the issues that you have already mentioned in your question: Protocol translation is an advantage of this architecture as it decouples the external API from the protocols internally used. On the other hand, increased complexity due to having another component to be maintained is mentioned as a drawback.
The second article also suggests some existing libraries (namley Netty, Spring Reactor, NodeJS) that can be used to implement an API gateway, so you might want to spend some time evaluating these for your project.
I am in the process of learning about microservices and there's one thing that I can't seem to figure out and I can't find any resources that give me a direct answer to this. The question is:
Do microservices involve only business logic and database interactions
or do they involve UI components like JS, CSS, HTML as well ?
There really isn't a notion of what tiers are included in a microservice itself, however generally speaking, when referring to microservices most of the time you're referring to some back end based app. That begin said - there are companies out there - two that I've talked to directly that are building "microapps" - basically the backend service, facade and a portlet like interface that can be plugged into a federated portal through a layer of orchestration.
For the Java folks - think fully encapsulated JSR-268 like components that are run as independent processes running within a portal itself.
A microservice can be a complete application including its own UI, business logic and data.