Brainstorming on a new Angular directory structure
See original GitHub issueOverview of the issue
Today’s Angular directory structure is quite flat and it starts to bring a few challenges. We could use this issue to note the improvements that could be done.
├── entities
│ ├── country
│ │ ├── country-delete-dialog.component.html
│ │ ├── country-delete-dialog.component.ts
│ │ ├── country-detail.component.html
│ │ ├── country-detail.component.ts
│ │ ├── country-dialog.component.html
│ │ ├── country-dialog.component.ts
│ │ ├── country-popup.service.ts
│ │ ├── country.component.html
│ │ ├── country.component.ts
│ │ ├── country.model.ts
│ │ ├── country.module.ts
│ │ ├── country.route.ts
│ │ ├── country.service.ts
│ │ └── index.ts
Motivation for or Use Case
There are several problems we encounter with this flat structure.
Same entity name in several MicroServices collide in the Gateway
There is already an issue about this. Basically, we use several microservices and aggregate them into a single gateway. Some Entities are redundant (eg. Organisation, Contact, …) and exist in several microservices (event though they don’t have the same attributes). With this flat directory structure, you end up with twice the same entity. To avoid this, we need to add the AngularJSSuffix, but it’s not really nice.
Module inter-connection
Today, the client model in Angular is not typed. We use the BaseEntity
for relations (here, an Organisation
has one Country
):
export class Organisation implements BaseEntity {
constructor(
public id?: number,
public name?: string,
public country?: BaseEntity,
) {
}
}
When we type this (and I hope JHipster will one day):
export class Organisation implements BaseEntity {
constructor(
public id?: number,
public name?: string,
public country?: Country,
) {
}
}
We end-up with modules depending on each-other. Same for the attempt being done now about auto-complete fields for the entities. Basically, these components can be shared by any other, so modules depend on each other.
Related issues
- Same entity name in several MicroServices collide in the Gateway
- Auto-complete fields for the entities
- Strong typing the client model in Angular
Suggest a Fix
If you take all these constraints into consideration, it looks like the directory structure could be improved:
- have a sub-directory per microservice
- have a shared directory per microservice (with model, service and other shared components such as the selection)
Sub-directory per microservice and shared directory
This could look like this:
├── billing // microserivce
├── invoicing // microserivce
├── scanning // microserivce
│ ├── entities
│ │ ├── country // notice that model and service are not there
│ │ │ ├── country-delete-dialog.component.html
│ │ │ ├── country-delete-dialog.component.ts
│ │ │ ├── country-detail.component.html
│ │ │ ├── country-detail.component.ts
│ │ │ ├── country-dialog.component.html
│ │ │ ├── country-dialog.component.ts
│ │ │ ├── country-popup.service.ts
│ │ │ ├── country.component.html
│ │ │ ├── country.component.ts
│ │ │ ├── country.module.ts
│ │ │ ├── country.route.ts
│ │ │ └── index.ts
│ │ ├── shared
│ │ │ ├── model // every model
│ │ │ │ ├── country.model.ts
│ │ │ │ └── organisation.model.ts
│ │ │ ├── service // every service
│ │ │ │ ├── country.service.ts
│ │ │ │ └── organisation.service.ts
│ │ │ ├── selection // every selection component
│ │ │ │ ├── country-selection
│ │ │ │ │ ├── country-selection.component.html
│ │ │ │ │ ├── country-selection.component.ts
│ │ │ │ │ ├── country-selection-multi.component.html
│ │ │ │ │ └── country-selection-multi.component.ts
│ │ │ │ └── organisation-selection
Some components can get quite complex, use helper classes or css. I quite like the “sub-directory per component”, but that’s another step further, not sure it’s really needed
├── scanning
│ ├── entities
│ │ ├── country
│ │ │ ├── country-delete-dialog
│ │ │ │ ├── country-delete-dialog.component.html
│ │ │ │ ├── country-delete-dialog.component.ts
│ │ │ ├── country-detail
│ │ │ │ ├── country-detail.component.html
│ │ │ │ ├── country-detail.component.ts
│ │ │ ├── country-popup.service.ts
│ │ │ ├── country.module.ts
│ │ │ ├── country.route.ts
│ │ │ └── index.ts
i18n
And of course, i18n also comes to play. So instead of having a flat directory structure:
├── i18n
│ ├── en
│ │ ├── address.json
│ │ ├── contact.json
│ ├── fr
We would also seperate it per micr-service
├── i18n
│ ├── billing // microserivce
│ ├── invoicing // microserivce
│ ├── scanning // microserivce
│ │ ├── en
│ │ │ ├── address.json
│ │ │ ├── contact.json
│ │ ├── fr
Menu
Today the UI shows an “Entity” menu, with all the entities. Again, it should be split into sub-menues (one per microservice) and then, have all the entities of this microservice list.
JHipster Version(s)
4.10.2
Issue Analytics
- State:
- Created 6 years ago
- Comments:35 (35 by maintainers)
Well, maybe the John Papa guide has evolved since when the Angular support was added in JHipster, but if you look at the Guide Overall Structural Guidelines, model and services are in the
shared
directory, to avoid module inter-dependency. As I said, today the JHipster model is not typed (usingBaseEntity
) that’s why we are safe and don’t have a big ball of mud.Model and services should be in
shared
. Now, when it comes with the new selection components, they should also be inshared
Probably because this is what we have also server side and it is difficult to do otherwise without having business requirements to help for taking decisions.