Feathers: Component-based architecture

Created on 22 Dec 2019  路  5Comments  路  Source: feathersjs/feathers

The problem / idea

I am working on front-end a lot and what I find really convenient is that they're component-based structures. This is common in Angular, React and Vue.

E.g. a component 'user' has the following structure

user/
   user.component.html
   user.component.scss
   user.component.test.ts
   user.component.ts
   user.translations.ts

What is so convenient about this? Well If I want to reuse this in another project, i can just move the 'user' component because it has everything it needs inside that folder

How does feathers v4 currently look

Example:

src/
   hooks/
     isAdmin.ts
   models/
     user.model.ts
   services/
      user/
         user.hooks.ts
         user.service.ts
test/
   services/
     user.test.js

My proposed solution

src/
   services/
      user/
         hooks/
            isAdmin.ts
         user.hooks.ts
         user.service.ts
         user.test.ts
         user.model.ts

Why / potential use cases

  • Well if a new developer asks, where do I find x for user?
    Currently you can answer it depending on what 'x' is, if it's test it's a different place, if it's hooks it's a different place.
    With the new proposed architecture, it does not matter what 'x' is, you can always point to the user service to find everything regarding the user
  • If a developer checks out your project, and find a really cool service named 'somecoolservice'. With the new proposed architecture you can say, yeah sure go ahead and just copy 'somecoolservice' into your project

Potential downfalls

  • Where would you place a hook that is useful for multiple services ? Do you keep 'isAdmin' in user service and require it from there in other services, or create a shared / lib folder? This can be hard to answer
  • Where would integration tests and tests that not only apply to one service be placed? This can be hard to answer
Discussion

Most helpful comment

As a reference, there already has been a long discussion related to this three years ago in https://github.com/feathersjs/generator-feathers/issues/95 (and somewhere else that I can't find at the moment). The hooks in a global folder was basically me being lazy and not wanting to figure out if it's a hook for a single or multiple services 馃槃

What I'd really like to have for v5 is a CLI and generator that lets you do any of those things and customize them if you want. I think I mentioned before that CLI tools and generators are notoriously thankless open source projects to maintain as a monolith providing any option anybody might want.

This is why I like the approach of http://www.hygen.io. It allows to keep the template in your project so if you want to change where the file goes, don't like the semicolons or want everything in a single file you can just change it. It could provide default or third party templates that you can install globally and if you want to change it you can "eject" the template files into your project. I'll create a follow-up issue for that in a bit.

All 5 comments

I think you can create something like this,
Currently we have a structure suits per project, https://microsoft.github.io/just/ allows us to create fast generators.

But lets not forget feathers allows us to create backend services. So issues like scaling, more pressing issue I assume. eg. #939

One of the best things feathers provides a utility structure not an app structure allows us to manipulate data easyly. I know it's really far away example but bullma css framework gives you structure, tailwindcss gives you utilities which you can shape UI very easy.

if we move a stucture as component we bind our code to that specific project.

@issy123, what you are proposing is actually my preferred file structure. I proposed this years ago and the main reason that people didn't like it came from the people using ORMs. They really liked having all of their model files in the same folder. I prefer a single folder for everything, including tests. It's only a couple of small tweaks to an app to support this layout, so that's what I currently do.

As for the issues you mention.

  • We already have a src/hooks folder for hooks shared between services.
  • Cross-service tests could go in the same place they are currently generated.

As a reference, there already has been a long discussion related to this three years ago in https://github.com/feathersjs/generator-feathers/issues/95 (and somewhere else that I can't find at the moment). The hooks in a global folder was basically me being lazy and not wanting to figure out if it's a hook for a single or multiple services 馃槃

What I'd really like to have for v5 is a CLI and generator that lets you do any of those things and customize them if you want. I think I mentioned before that CLI tools and generators are notoriously thankless open source projects to maintain as a monolith providing any option anybody might want.

This is why I like the approach of http://www.hygen.io. It allows to keep the template in your project so if you want to change where the file goes, don't like the semicolons or want everything in a single file you can just change it. It could provide default or third party templates that you can install globally and if you want to change it you can "eject" the template files into your project. I'll create a follow-up issue for that in a bit.

I admit I was part of the push for having models in their own separate folder, and it happened at a time of sequelize integration... but it really had little to do with ORMs. Models IMO are completely separate and independent from the services that consume them, and they [can] serve purposes outside of the context of their associated service (eg. multiple services can consume a single model). Seeing all of your models in one place also has its advantages, especially when models relate to one another (which they often do).

All that said, I don't care if the generators put models and services together. I think the "modlet" pattern is tried and true and has unspeakable advantages.

As far as global hooks, I prefer to see service-specific hooks close to my services (as they currently are) and reusable non-service-specific hooks at a more global level. For example, role and permission checks aren't the same as the roles service, but rather deal with the headers/auth attached to every service - so I'd rather see those at a global level.

Like hooks, models can have multiple purpose, can be isolated or have relations with other ones.
So why not apply the same structure to models.
You can have local models related to only one service, and global models that are used by or related to multiple services or grouped together by relations.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rstegg picture rstegg  路  3Comments

jordanbtucker picture jordanbtucker  路  4Comments

ausir0726 picture ausir0726  路  3Comments

NetOperatorWibby picture NetOperatorWibby  路  4Comments

RickEyre picture RickEyre  路  4Comments