jhipster / generator-jhipster

JHipster is a development platform to quickly generate, develop, & deploy modern web applications & microservice architectures.
https://www.jhipster.tech
Apache License 2.0
21.4k stars 4.02k forks source link

Implement a micro frontends prototype with JHipster #10189

Closed mraible closed 3 years ago

mraible commented 5 years ago
Overview of the feature request

JHipster has a monolith frontend when using microservices. I think it’d be hip if we supported micro frontends too. It probably won’t be easy to implement since the patterns I’ve seen call for serving up the UI on the microservice itself, then including it into a gateway via that URL using SSI, ESI, or h-include.

Motivation for or Use Case

Micro frontends have moved from trial to adopt in ThoughtWorks Radar.

These resources explain some implementation options:

And this is a great podcast on how IKEA has implemented them:

There are a couple of frameworks that aim to simplify micro frontends too:

Once this prototype is complete, I'll open a new issue to create a blueprint or integrate it into JHipster itself.

atomfrede commented 5 years ago

My 2 cents to this and ideas:

So why microservices and microfrontends? Fo rme the most important part is the independence/freedom of each team responsible for a service. This contains independent deployments, freedom of choice when it comes to technology (within certain boundaries of course).

The current monolithic frontend leads to coupled deployments and each team is coupled to one frontend technology. So you can't select the technology which fits best for your team or the requirements. We have switched to a microfrontend architecture via tailor (started in 2016 and in production since mid 2016). So I would go with the "fragment" approach as described by tailor.

There are some things we should keep in mind. The current menu bar must be a separate UI, either served by e.g. the gateway or a dedicated service, such that the menu is only defined once. bitmap

To support inter fragment linking without using absolute urls we defined a custom uri schema, we could do same (if required). E.g. jh:user-management would resolve to the concrete url e.g. via a js api from the header bar. The header/menu fragment must be framework agnostic (e.g. using preact) and must be rendered blazing fast as there are possible hard page reloads when switching fragments.

The gateway must decide where to route a request. Either it is an api request so it must be routed to the backend service api. It can be an asset request (e.g. images, scripts delivered by the microservcice) or a layout request which must go to the layout service.

PSun3i8m38NXFQV81Ne5L5XO40nL3n2bXaQaCN8TK6-FG81UyMJfVuE_TjOWMgViCftLAtj9br7za8IY9YukH6Nn_KpY8aytBbJKxuFI8onG3c7XgXt9FKM2tesKiyqxvgkjsweZY-r7xfEjVJgLl7oxUn5zqsn-kCzzjpKF5mJYW4JiY5mloCJ-3rrPhC7EAB4hUinklhTKXZhb9m00

So the most challenging part is the gateway and developer experience imho.

As there must be a lot of routes defined (or auto discovered), not sure what to use there. The related project mosaic projects seem quite good and they can be configured via an api (we have a custom UI gateway based on vert.x so routes are fixed).

There are now multiple components required to develop a service (layout, shell/menu, gateway).

So whats the concrete idea here?

atomfrede commented 5 years ago

I will provide a small proof of concept using tailor/mosaic here https://github.com/atomfrede/jh-10189-poc/tree/master. If that works out well we can go on with a real world prototype using real jhipster services and authentication etc.

atomfrede commented 4 years ago

@mraible Just to keep you updated, I have first version with spring cloud gateway, a simple shell service, tailor based layout service and will try to create two fragment services during the next week. When that is done we should have a look at how to integrate auth etc.

mraible commented 4 years ago

That's awesome! Thanks for the update.

On Sep 13, 2019, at 13:53, Frederik Hahne notifications@github.com wrote:

@mraible Just to keep you updated, I have first version with spring cloud gateway, a simple shell service, tailor based layout service and will try to create two fragment services during the next week. When that is done we should have a look at how to integrate auth etc.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

joewhite101 commented 4 years ago

To add some support, thoughts, and potential opportunities for contributions around MFEs.

The TL;DR We find micro-frontends very interesting. We're doing a bunch of JHipster and micro-frontend (MFE) work in a JH blueprint in the open source world. Might be a chance to promote some of that up to mainline JHipster.

I am the CTO at Entando (an open source company) that is doing a lot of work around Micro Frontends and modernizing what we do from a development perspective. We're migrating our plugin and widget architecture to JHipster generated microservices and micro-frontends now.

We're actively working on generating a collection of micro-frontends using JHipster from JDL or an entity that we can then composed into a complete application using our engine and App Builder application. For example, each entity will have an MFE for a table, detail view, and form in MFE form. All exposed as custom elements.

We're using JHipster for our microservice generation (with customizations via blueprint) and adding the MFE generation to our blueprint.

As we get further into our development, if it is interesting to the community/team, we would be open to moving our MFE generation code up into the mainline generator and out of our blueprint.

We're also going to be doing work around making the spring boot services for JH more kubernetes focused. We've got an operator and some sidecars now to tie it all together including our JH services. If there is ever interest in a more K8s flavored Jhipster we could pull some of that up into the main project as well.

You can follow along on our github as well if there is interest: Our blueprint (no MFEs yet but soon): https://github.com/entando/entando-blueprint

The base POCs for generated widgets that we'll eventually migrate into the blueprint: https://github.com/entando/generated-widgets

Some K8s stuff: https://github.com/entando/entando-k8s-operator https://github.com/entando/entando-component-manager

cc @salaboy for k8s and operator thoughts

joewhite101 commented 4 years ago

We've updated our blueprint to generate Micro-frontends using custom elements based on entities processed through JHipster.

For each entity we generate a React MFE including a table, details view, and form. Each MFE also exposes custom events that are consumable by the other MFEs on the page. We're working through the full flow between MFEs now.

An example event flow,

The objective is to standardize the custom events so that they can be easily consumed by other MFEs (or other assets generally) on the page.

Latest is here https://github.com/entando/entando-blueprint

salaboy commented 4 years ago

@joewhite101 awesome stuff!

sendilkumarn commented 4 years ago

@joewhite101 Good stuff!

mraible commented 4 years ago

@joewhite101 Can you please provide the steps necessary to try out your blueprint? I'd like to take a look and try it.

Related: I stumbled across https://github.com/eavichay/microfronts today. Seems lean and mean, but also pretty new.

MathieuAA commented 4 years ago

@mraible if you try microfronts, keep us posted! I, too, found my way to the repo. Unfortunately I haven't had the time to dive into it.

atomfrede commented 4 years ago

Microfronts looks a lot like zalandos approach with tailor but done in the frontend, very interesting. Need to find some time to complete the prototype with project Mosaic/tailor

joewhite101 commented 4 years ago

Hey @mraible, @MathieuAA and @atomfrede, and others,

Here are some intro instructions and links. We're also working to keep the READMEs up to date and the generator itself creates a README inside of the generated MFEs. Refer to those as this post ages for more up to date instructions.

A quick summary of where we are at now is at the bottom. Some of the work here is related to things we have specifically in flight at Entando but it should be relatively straightforward to disconnect the MFEs for other uses as desired.

Run JHipster with the Entando blueprint Detailed Steps:

  1. Note that we're on 6.3.0 jhipster still but it works with later versions. You may need to add --skip-checks to the blueprint call
  2. Clone the Entando blueprint git clone https://github.com/entando/entando-blueprint.git
  3. Go into the blueprint on the command line cd entando-blueprint
  4. Link the blueprint npm link
  5. Create a new project to run your jhipster (not inside the entando-blueprint) mkdir myproject
  6. Go to the project cd myproject
  7. Link the entando blueprint npm link generator-jhipster-entando
  8. Run jhipster with the blueprint jhipster --blueprints entando
  1. In the prompts there is a required choice. If not noted below you can pick whatever makes sense. 7.a must pick microservice

Now add entities to the project (make sure you're still linked to the blueprint. Mine gets unlinked for some reason but i seem to be alone on this). You can follow the normal flow for adding entities here. Once difference is that at the conclusion of the entity flow a call to npm install will be made to install prettier to format the generated MFE code. If your npm requires sudo see known issues below.

Detailed steps for the entities

  1. jhipster entity <myEntityName>
  2. Add fields as desired
  3. Required choices: 3.a For Do you want to use separate service class for your business logic? You must Pick one of the two Yes options if you want to use the out of the box filtering available in the table MFE. If you don't pick it the MFEs will still work but won't have filtering. 3.b For Do you want to add filtering? Pick Dynamic filtering for the entities with JPA Static metamodel. It is used for filtering in the table MFE (but can be skipped if you don't want filtering)

At the end you'll be prompted to override a file called descriptor.yaml. You can safely pick Yes for this prompt. It is a file used in generating Entando bundles.

Output For each entity the blueprint will generate a details, table, and form MFE. You can see the MFEs in your project in ui/widgets/<entity>/

Running the MFEs There are detailed instructions on running the generated MFEs in the README file in the folder for the MFE itself (like /ui/widgets/<entity>/tableWidgets). Or you can read the version that lives here: https://github.com/entando/generated-widgets/tree/master/react/details

Known Issues

joewhite101 commented 4 years ago

You can also follow along with our work in progress for our general docs updates here with instructions that are more nicely formatted. The general steps are the same but there is additional focus outside of the MFEs

https://es-entando.github.io/build-your-first-app/#entando-blueprint

mraible commented 4 years ago

@joewhite101 I tried the tutorial today and was able to make everything work. Nice work!

A few things I thought of:

  1. If we allowed microservices to have a keycloak.yml for Docker Compose, it would greatly reduce the steps in your tutorial because you could just start Keycloak.
  2. Your blueprint uses Create React App, which is cool, but I believe we should be able to use JHipster's React CRUD support.
  3. How do you envision including this micro frontend in a JHipster gateway?

I propose we use something like the following to implement micro frontends in JHipster:

  1. Prompt the user for micro frontend support as an option (or make it the default).
  2. If micro frontend, generate the client code in the microservice instead of in the gateway.
  3. Modify the gateway when the UI is generated to add a route and lazy-load the code from the microservice.
  4. Initially, only support OAuth 2.0 for micro frontends. That way, we won't need to generate client code for authentication. We can just add .oauthLogin() to the microservice and it'll redirect to the IdP, then back to the UI.

The only micro frontends with this setup would be entities that are generated. Since we already have those available at different routes, I think this will work. We might need to do some additional work to figure out how to load a micro frontend into another micro frontend, but I think using segmented-by-route is a good start.

@jhipster/developers What do you think?

joewhite101 commented 4 years ago

@mraible Great points. A few notes and thoughts.

  1. We allowed microservices to have a keycloak.yml for Docker Compose, it would greatly reduce the steps in your tutorial because you could just start Keycloak.

Good idea. We will add this.

  1. Your blueprint uses Create React App, which is cool, but I believe we should be able to use JHipster's React CRUD support.

I don't remember exactly why we chose create react app but we can take a look at the JHipster CRUD for sure. I'll have to check with my team. Giuseppe or Martynas can you add some more detail here?

  1. How do you envision including this micro frontend in a JHipster gateway?

This step is where we diverge a bit from the JHipster architecture. We are building a Micro Frontend composition engine for Kubernetes and our objective is to take the SpringBoot service and the MFEs and wire them into our composition engine. And our users can also use an Entando Digital Exchange (marketplace) to deploy the services and MFEs. So rather than embedding them in the gateway we plan to provide builds and steps to deploy them to an Entando app.

However, it doesn't look like it would be a huge amount of work to provide different options post generation on how/where somebody wants to deploy and host their MFEs. Could also be useful to use JHipster MFEs to embed in legacy applications via custom elements. Provides a path for JHipster as a way to modernize legacy apps in a modular way.

So as long as we design carefully we could have multiple good choices. The Gateway support would be a great area for somebody to join us on the MFE generation journey. We'd help with the blueprint understanding if somebody wants to jump in.

  1. Prompt the user for micro frontend support as an option (or make it the default).

Good idea. We will add the option.

  1. If micro frontend, generate the client code in the microservice instead of in the gateway. Modify the gateway when the UI is generated to add a route and lazy-load the code from the microservice.

Makes sense to me. I think gateway as a follow on step or integration option makes a lot of sense given the utility of MFEs in different deployments.

Initially, only support OAuth 2.0 for micro frontends. That way, we won't need to generate client code for authentication. We can just add .oauthLogin() to the microservice and it'll redirect to the IdP, then back to the UI.

We'll review this and can help if the team thinks it is the right way forward. Seems like a good approach. We have some built in identity management assumptions in our environment for the composition layer. But we can look at abstracting so that what you recommend could be the default or an option and give some flexibility on how the MFEs tokens are managed.

pascalgrimaud commented 4 years ago

@atomfrede : what is the state of this ticket plz ?

atomfrede commented 4 years ago

Sadly I didn't made much progress. But I think Matt tried a different approach which might fit better.

mraible commented 4 years ago

Yes, I plan on trying the Module Federation that's coming in Webpack 5.

https://github.com/module-federation

If folks are interested in helping with this effort, I can create tickets with small tasks and assign bounties to them. Here's a high-level plan:

  1. Create a microservices architecture using JHipster 6.9.x. My blog + store JDL is probably a good start.
    1. Modify things so the UI code for each microservice resides within each microservice.
    2. Modify Webpack build to use module federation.
  2. Integrate Micro Frontends as an option in the generator (only for microservice)
  3. Upgrade to Webpack 5 beta.
  4. Add Webpack module federation and make Micro Frontends work.
  5. Test and iterate ensure you can develop a microservices UI stand-alone or with an app shell (aka a gateway app).

I think we should only target OIDC for now because it'll make authentication into the standalone apps the easiest. If we want JWT support, the stand-alone apps will need their own shell and login UI.

gidesan commented 4 years ago

Hey @mraible, I'd like to help. I'm not a webpack guru but I'm following with great interest all the module federation stuff since a couple of months. I'm working with @joewhite101 at Entando.

mraible commented 4 years ago

@gidesan Cool! Do you have any feedback on the high-level plan? Are there things I'm missing?

mraible commented 4 years ago

I started trying to upgrade a microservices architecture with Angular to use Webpack 5. I made progress, but ultimately failed. You can see my PR with changes at https://github.com/mraible/jhipster-microfrontends-angular/pull/1.

gidesan commented 4 years ago

@mraible your high-level plan sounds good to me, but MF is not feature-complete yet, lots of things are being added. Does it make sense to wait for a Webpack 5 RC / final version?

mraible commented 4 years ago

@gidesan Possibly. However, I think trying to make it work now may give us an opportunity to provide feedback and fixes before everything is final.

mraible commented 4 years ago

I created a couple repos with PRs to try and upgrade JHipster v6.9.0 to use Webpack 5. Both attempts failed. The respective PRs have more information.

joewhite101 commented 4 years ago

I may try and pick up where @mraible left off. However, i'm the furthest thing from a webpack expert so it will be slow going. If there is a webpack expert out there who wants to take the lead I'm happy to follow.

FWIW We're looking at module federation as a pretty key technological update in webpack 5 for micro frontends. Seems like a pretty compelling use case.

cc @gidesan

jsantoru commented 3 years ago

@joewhite101 @gidesan - just curious on what the state is with leveraging module federation, and if that's still the planned direction.

joewhite101 commented 3 years ago

It is still the planned direction from my perspective but haven't made any progress. Busy in some other areas and with day job. I think that module federation and webpack 5 are the killer feature here.

Feel free to take this if you want.

mraible commented 3 years ago

Angular CLI added experimental opt-in support for Webpack version 5 in v11.0.0-next.3.

https://github.com/angular/angular-cli/issues/17555#issuecomment-701359679

github-actions[bot] commented 3 years ago

This issue is stale because it has been open 30 days with no activity. Our core developers tend to be more verbose on denying. If there is no negative comment, possibly this feature will be accepted. We are accepting PRs :smiley:. Comment or this will be closed in 7 days

mraible commented 3 years ago

Commenting to keep open and active.

mshima commented 3 years ago

@mraible https://github.com/mshima/jhipster-microfrontend

mshima commented 3 years ago

Just made cypress to succeed. A few notes about the implementation:

github-actions[bot] commented 3 years ago

This issue is stale because it has been open 30 days with no activity. Our core developers tend to be more verbose on denying. If there is no negative comment, possibly this feature will be accepted. We are accepting PRs :smiley:. Comment or this will be closed in 7 days

mshima commented 3 years ago

Support is almost ready, waiting for angular 12.

github-actions[bot] commented 3 years ago

This issue is stale because it has been open 30 days with no activity. Our core developers tend to be more verbose on denying. If there is no negative comment, possibly this feature will be accepted. We are accepting PRs :smiley:. Comment or this will be closed in 7 days

avdev4j commented 3 years ago

Keep it open

pascalgrimaud commented 3 years ago

@avdev4j : I'd like to know what can be done on generator-jhipster side ? I thought this part was done by Entando blueprint, unless I'm wrong ?

avdev4j commented 3 years ago

@pascalgrimaud here are several things here. Entando's blueprint allow the user to generate an MFE app within his entity to deploy it into the Entando platform. It matches well with the Entando way of work and features but not probably with the a most common micro frontend architecture.

This is @mshima worked on the Webpack 5 upgrading to be able to use the module federation feature (yes, it comes with Webpack 5) to make the JHipster generated app a micro frontend based application.

From my POV, another step would be to be able to directly generate MFE with JHipster as we can do with microservices (aka adding a new applicationType). But for this last thing, I don't really know if it's something some people work on or just an idea in my mind :D.

mraible commented 3 years ago

@pascalgrimaud We currently generate a monolith UI, which kinda breaks the whole point of microservices. A monolith UI on the gateway means a microservice + gateway needs to be redeployed when there's changes. With microfrontends, only the microservice that's updated needs to be redeployed.

github-actions[bot] commented 3 years ago

This issue is stale because it has been open 30 days with no activity. Our core developers tend to be more verbose on denying. If there is no negative comment, possibly this feature will be accepted. We are accepting PRs :smiley:. Comment or this will be closed in 7 days

mshima commented 3 years ago

The generator part is kind of ready. Needs angular 12.

github-actions[bot] commented 3 years ago

This issue is stale because it has been open 30 days with no activity. Our core developers tend to be more verbose on denying. If there is no negative comment, possibly this feature will be accepted. We are accepting PRs :smiley:. Comment or this will be closed in 7 days

mraible commented 3 years ago

I'm still interested in this feature.

On Jun 7, 2021, at 18:55, github-actions[bot] @.***> wrote:

 This issue is stale because it has been open 30 days with no activity. Our core developers tend to be more verbose on denying. If there is no negative comment, possibly this feature will be accepted. We are accepting PRs 😃. Comment or this will be closed in 7 days

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

mshima commented 3 years ago

Rebased the microfrontend branch, and took a while to discover that zone.js needs to be imported as umd.

PR created, I will create a series of PRs for minor improvements. The last commit will need much more work, so I will try to remove it in the end.

i18n is not working correctly for microservices, need to fix lazy loading microservice translations.