How to create a scalable and maintainable front-end architecture

Kevin Pennekamp on August 26, 2019

Modern front-end frameworks and libraries make it easy to create reusable UI components. This is a step in a good direction to create maintainable ... [Read Full]
markdown guide
 

Wow, great write-up! Thank you for going into so much detail and the graphics, they make things so much clearer.

 
 

How scalable is one redux store for an entire application?

 

Hi William,

My first tip would be not to depend on only one thing. It was one of my own bigger mistakes made in the past. I choose a technology and tried to apply it as much as possible, making my own life even more difficult.

That aside, state management is difficult and many different solutions exists. I do not think there is one solution you can choose for a big front-end application. You should always question yourself: do I need this state on application level, or is it only required in a more scoped environment? Some examples you can use for state-management techniques, than can be combined are:

  • Redux for your application state, mainly for sharing data between different parts of your application. Here you can also manage errors and request states (e.g. loading) with a proper reducer design. You could for instance create a generic reducer setup for CRUD operations (only the name will be dynamic), making it more scalable;
  • Redux for application settings and configurations that only need to exist on the front-end;
  • React Context on an application level for maintain states around for instance small configurations, like language. Choosing only Context, you make it only dependent on React, making it more sharable between projects, but also within the project. Otherwise choosing a correct big store-design would become more difficult. And React Hooks made this a lot easier;
  • Use the cache from API clients, if available. Apollo Client for GraphQL is a great example of a client having this. This might be sufficient for your state management;
  • Use React Context for module state. Sometimes you just need state management within the pages of a module, and nowhere else. Maybe you have a complex page with a lot of nested components, all working on the same object (or objects related to each other). Or you need to maintain a state of requests you need to send when clicking save (e.g. creating and updating multiple objects), just to keep front-end and back-end consistent in data. In such a case, React Context might be the better way to go. Personally I often combine it with a reducer (using React.useReducer), which are similar to Redux reducers. So it is like lifting one reducer up into your application and apply it more scoped. The biggest advantage of React Context here, is that you can combine state with functions, both that can be used by any component living within the context.
  • Use a Reducer for individual API calls. I used to call every API through redux, as I could easily manage states of requests (e.g. loading, successful executed, or did we get back an error). But if this is the only goal for using Redux, than just create a generic function you can use for outgoing calls, that uses a small reducer. Robin Wieruch has a great article around this, using Hooks (robinwieruch.de/react-hooks-fetch-...).

In summary: yes, Redux can be used for application state and it can be scalable. You as a developer just has to make the decision where which part of the state needs to live, as not everything needs to be in the application store.

 
 

Great post,
I love how you introduced the pattern without attaching it to a specific frontend framework.

Thanks!

 

Thanks! That was also one of my goals when starting this article. Good to see that it is also noticed

 

This is very useful. Thank you for explaining these concepts and good examples. Much appreciative.

 
 

This is really interesting.
Thank you :D

 
 

You don't have a test folder? I will never trust you :D

 

Ha you got me there! I found that everybody has their own way of ordering tests. My tests are almost never in a single folder, but are on that level that makes them shareable with the code across projects. As an example, I have a __tests__ inside the lib and in some cases even nested one level further.

 

Great article, Kevin! I was wondering which tool did you use to create those schematics. They look clean and simply awesome!

 
 
 

Would you suggest VueJS for the application that is based on microservices?

 

If you mean that a microservices architecture for your back-end (e.g. running on a kubernetes cluster): yes. Any of the modern front-end frameworks can work. It is more importantly that you create a good API gateway on top of your microservices, to ensure your front-end talks to one service (the API gateway) only. This has different advantages, like: good user access control on API level, ensure certain services cannot be touched by the front-end, create API calls specifically for your front-end (e.g. Best-For-Front-end structure with GraphQL) just to name a few. With a good API gateway on top of your microservices, it should not matter if you use React, Vue, Svelte or any other framework.

I find the architecture I describe especially working well when used on top of big applications consisting of a solid front-end, a highly available API gateway, and a microservices application as a back-end.

code of conduct - report abuse