-
Notifications
You must be signed in to change notification settings - Fork 475
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Top-level routing #21
Comments
My team and I are also working on the same. We aren’t at the stage yet where we can split our monolith yet, but this question has been on our mind as well. |
With https://github.com/square/misk-web, our initial approach has developed into two idioms for sub-routes. 1. Sub-routes can only be extensions of the url domain of the component
2. Components can not have overlapping url domainsAssume in the following example that components are added in the order of the table rows.
|
Lay down your burdens you need to rethink, what URLs have been originally been used for - to link to an application at a certain state. In the time of SPAs we abused the URL for all sort of state-related things in our apps - we used it to route to a certain state of the app (by associating URLs with components). If we were to navigate to another state of the app, we triggered fake URL changes. However as time passed by, we figured out, that the state of a SPA needs special care and thus we all craved a dedicated state management (being it Redux, Mobix, ...). If you look at the typical things the router in SPAs is doing right now, it becomes clear, that this is just an awkward mechanism to change the state of the app. But for changing the state of an app we do not need a router - we can just dispatch the corresponding actions and have generic router-less state router component listen for the state changes and thus load components accordingly. If you see it that way you will solve the main problem - different components competing for using the URL (by using a router) as their sole source of state initialization. If all components are decoupled from the URL and are only using an in-memory based native state management aware routing, they will now all happily live together on the same page. For communication between components you have to use either DOM events or attributes. How about "deep-linking" into micro frontend based apps? Depending on your micro frontend architecture - you might have a glue app (we call it the frame in our architecture) that is orchestrating all the components. As all components have been decoupled from the URL, the glue app can now utilize it again to (re)store the state of each component. The frame knows about the state changes between components and can encode this global state in the URL. Usually the state is to big to be kept in the URL anyway and thus it is feasible to store the serialized application state either locally or remote and associate it with a GUID / token that allows for restoring - i.e. once the frame has been passed the GUID it uses it to restore the state of all components. That is the generic idea; we are using it in production by replacing the Angular Router in a Angular Elements app with a native NgRx aware (but still somehow compatible version) URL-less one. That way we can load multiple Angular Elements apps on one page. |
@adrw I have to give your micro frontend architecture a try. Thanks for posting it! If I understood it correctly you have certain conventions what URLs (and sub paths) are mapped to certain components. This is a viable choice, but it needs coordination between teams to avoid naming collisions. Ultimately it weakens the isolation of components and might lead to problems in scaling - i.e. when certain conventions cannot be enforced easily any more (read: third party supplied components). In our (above) approach we simply remove the dependency on the URL altogether, while still maintaining the possibility of deep-linking into app state. This allows for a better isolation of components by avoiding potential naming collisions on the URL. Of course, GUID-based URLs are not so pretty(TM) and might scare away SEO magicians; but people simply do not memorize URLs any way. Even the most "SEO-optimized" URL will end up either as a bookmark or an entry in the browser history and therefore we have no problem with "ugly" URLs. |
I would disagree... I personally use individual URLs very often. Especially with the autocomplete of modern browsers Example:
so by just selecting the appropriate URL I can go to where I need to be...
that experience would be rather different. so I agree storing the full state in the URL is not possible for an application... but certain entry point should still have their easy human-readable path... Unfortunately, I don't have a ready and good alternative solution... I guess it should be a combination of a "critical path" + data. |
@ChristianUlbrich I really like the idea of separating state from the url. This is something I have tried to solve and still haven't found a good solution for. I see the same problems as above. I do agree that URL is critical in the User Experience as this is a functionality commonly used and known to shortcut to desired pages. But how does the frame know when a components state should be referenced in the url someway? Lets say I have a site and a team is working on a Users component and they want to display user "10". This is easy with state as we will see a request to get user "10" and then the component will populate. Now the problem comes in on refresh, lets say the clients wants user "11" and just replaces the url "/user/10" => "user/11" how is this translated and known? |
@brion-fuller , I have faced the same challenge in one of my recent projects. We were trying to encapsulate all ui for a micro service in single web component (custom element) and had a shell application to compose these elements in some fashion. One requirement for us was that each view should be addressable by url to allow bookmarks. The way we solved the problem was to expect a In the shell application that composed these components, we applied a simple heuristic for routing: This allowed us to serve up our web components in a shell application, but also able to use them in other web applications that works differently. For instance, we used some of these components in a ASP.Net web forms application, without making any changes. |
Hi there, https://github.com/me-12/single-spa-portal-example He does reverse proxying through Webpack. It's actually unnecessary, you can just pass the URL where the entrypoint.js files are hosted. |
Hi there,
I hope I'm writing in the right section (otherwise I'll move it wherever it belongs).
I've been trying to implement the microservice architecture but even though I managed to run two different applications on the same page, I've been struggling a bit to get how to implement a proper routing.
In the website and in the videos I watched you talk about a top-level routing. Has this to be implemented in NGINX (for instance)?
How should I use this model if I need to create routes at the component level, like inner/sub-routes?
Many Thanks,
A.
The text was updated successfully, but these errors were encountered: