question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Brainstorming on a new Angular directory structure

See original GitHub issue

Overview 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

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:closed
  • Created 6 years ago
  • Comments:35 (35 by maintainers)

github_iconTop GitHub Comments

3reactions
agoncalcommented, Nov 17, 2017

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 (using BaseEntity) 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 in shared

0reactions
gmarzioucommented, Feb 3, 2018

I can see that slowly the suggestions are mimicking package by type

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.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Workspace and project file structure - Angular
A project is the set of files that comprise a standalone application or a shareable library. The Angular CLI ng new command creates...
Read more >
Angular File Structure and Best Practices (that help to scale)
The Angular Structure​​ All of the app's code goes in a folder named src . Do structure the app such that you can...
Read more >
What are the Rules for effective Brainstorming? Ultimate Guide
Brainstorming sessions are wonderful group creativity technique which encourages a group of people to ideate freely without any fear of criticism to solve ......
Read more >
Working with Angular and its Technology Stack in .NET
Hosting an all-in-one application means that the entire application can be deployed under a single server instance. Having fewer moving pieces ...
Read more >
Browser Client AngularJS to Angular Migration
Key Code Changes · Angular services, components, etc. have different structures · Lazy-loading, nested routing. · Move to TypeScript · Using ES6- ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found