bcgov / entity

ServiceBC Registry Team working on Legal Entities
Apache License 2.0
23 stars 59 forks source link

Use a store for business logic; components should handle display logic #15431

Open jonathan-longe opened 1 year ago

jonathan-longe commented 1 year ago

What is the problem?

At present, nearly all the business logic is stored in components. This was the right choice when the application was small, but as the application grows it makes more sense for the business logic to be written elsewhere. It's critical that developers agree on an application architecture so that we're working towards a common goal.

What is the impact?

When business logic is written into Vue components it's impossible to reuse elsewhere. For example, if business logic is written into the header bar, it can't be reused by the footer -- they're two different components. The impact is that our code is less flexible.

Proposed solution

Components should be used only for display since they represent a location on the page. Business logic should placed in the Pinia store so any component can display the data it needs.

Some might suggest that business logic should be placed in Vue "mixins" instead of the Pinia. While it's true that mixins allow some code reuse and it's definitely better than placing the business logic in components, mixins don't save state. If the header and footer components, both need to display the same data, the mixin would need to retrieve the data twice.

By using the Pinia store both the header and footer can share the same data and both can be instantly updated when a user clicks a button (an event) that mutates the state. (I'm using header and footer to illustrate components that physically separated from each other. There are better examples of components that are physically separate but need to share the same data, but a detailed knowledge of the application is required).

@severinbeauvais and I have been discussing the benefits and drawbacks of different architectures.

jonathan-longe commented 1 year ago

Updated the title to remove "Vuex" as I didn't mean to suggest Vuex over Pinia. Thanks Thor!

cameron-eyds commented 1 year ago

As Thor also mentioned in chat, i would look into Composables (via Vue Composition Api) as it seems to fit well with what you are looking for. They are designed for just this, reusable stateful logic. They are also relatively easy to implement, keep organized and granular to the 'category' of shared logic. ie header, footer, breadcrumb etc might be a navigation composable or whatever.

severinbeauvais commented 1 year ago

Following :popcorn:

jdyck-fw commented 1 year ago

Sub-tasks can be created for this ticket as needed. An RFC being one of them - likely with an estimate of 2. This RFC can be pulled into the sprint.