Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I can't understand "Layer your app, keep Express within its boundaries" second picture ? #252

Closed
alamenai opened this issue Sep 20, 2018 · 12 comments
Assignees

Comments

@alamenai
Copy link

alamenai commented Sep 20, 2018

Can any one explain more this example

@goldbergyoni goldbergyoni self-assigned this Sep 20, 2018
@bpinhosilva
Copy link

bpinhosilva commented Sep 20, 2018

It is kind of separation of concerns. Expressjs is a web framework. You use it for the http handling of your application. The idea is to keep it doing that not involving into your business logic. That's why it is recommended that you "layer" your app. The business layer, the web layer, data access layer and so on.
Once it deals with a request it passes it on to other layer that should know what to do with input data. And later on, the other layer send it back to return some information to the client who requested something (if this is the case).

@AbdelrahmanHafez
Copy link
Contributor

Once it deals with a request it passes it on to other layer

What would an example to another layer be? My classes?

One way I usually do things is that I have my mongoose models as parent classes, attach my business logic to them as methods, send the data from the request data to the method, and send back the response from the function(s) to the user again.

Is that a correct example of the rule?

@ericblade
Copy link

Let me see if I can try to come up with an explanation . . . thinks

So, ultimately, you probably want all the functions of your node application, to be able to operate on data regardless of the actual source of it -- You want to be able to use a test framework as the source of data, maybe you need to mock clients or servers that connect to it, or it connects to. Maybe you might even someday have a completely different layer of accessing it that doesn't even involve a web server.

The web server piece itself should serve solely as a layer to get data from the user, and pipe it into the application. The application shouldn't be dependent upon anything in the web server, and there shouldn't be anything tying them together, other than the point at which the data is transferred from the web server piece, into the application, and then returned to the web server client.

Does that make sense?

@bpinhosilva
Copy link

Once it deals with a request it passes it on to other layer

What would an example to another layer be? My classes?

Yes, you have classes or modules that delegate responsibility to others and so on.

One way I usually do things is that I have my mongoose models as parent classes, attach my business logic to them as methods, send the data from the request data to the method, and send back the response from the function(s) to the user again.

Is that a correct example of the rule?

Well, you could have, for example, a business class (or module) that knows the application logic and when necessary it fetches data from a database. In this case, you could have a reference to your mongoose model inside the business class that you ask for data. So the flow would look like:

client request -> web layer -> business layer -> data layer (mongoose) -> back all the way to return the data

Keep in mind that this varies a little bit from application to application. Nowadays you have models using active record pattern, so they also have methods to do CRUD operations.

If you attach business rules to your model it could be painful in the future. A simple change would chain many others in multiple files around your project. It could be suitable if the data layer knows how to deal with data itself and avoid what to do with them later (that's business layer responsibility).

@goldbergyoni
Copy link
Owner

goldbergyoni commented Sep 21, 2018

@XlintXms Welcome and thanks for the great question. This section deserves some clarification (did you notice that the second picture is an animated gif?)

Express has its own objects (req,res) which hold some of the request info like the user, his permissions, etc. You may get tempted to pass these objects to many of your application objects/classes. Everything works fine but then the product manager asks whether you can invoke your application not only through REST API but also using voice or using a nightly CRON job or as a desktop application - now you're in trouble since your entire app depends on Express objects (if you run CRON job or desktop app, where would you grab Express objects from...). The heart of your app, where your core logic is defined, should be coupled from the channel that invokes the logic. In other words, Express is just a gate to your app, not the app itself, and you want to keep the app flexible for any other gate. You may read more about ports and adapters here or about the DDD principle - 'isolate the domain'

These great explanations by @bpinhosilva and @ericblade also worth quoting:

client request -> web layer -> business layer -> data layer (mongoose) -> back all the way to return the data

The web server piece itself should serve solely as a layer to get data from the user, and pipe it into the application. The application shouldn't be dependent upon anything in the web server, and there shouldn't be anything tying them together, other than the point at which the data is transferred from the web server piece, into the application, and then returned to the web server client.

@bpinhosilva @ericblade You seem to have great explanation skills, we're starting soon to write our performance best practices + our boilerplate template with best practices - would love to see you join. We learn a lot by discussing, writing and coding best practices

@bpinhosilva
Copy link

@XlintXms Welcome and thanks for the great question. This section deserves some clarification (did you notice that the second picture is an animated gif?)

Express has its own objects (req,res) which hold some of the request info like the user, his permissions, etc. You may get tempted to pass these objects to many of your application objects/classes. Everything works fine but then the product manager asks whether you can invoke your application not only through REST API but also using voice or using a nightly CRON job or as a desktop application - now you're in trouble since your entire app depends on Express objects (if you run CRON job or desktop app, where would you grab Express objects from...). The heart of your app, where your core logic is defined, should be coupled from the channel that invokes the logic. In other words, Express is just a gate to your app, not the app itself, and you want to keep the app flexible for any other gate. You may read more about ports and adapters here or about the DDD principle - 'isolate the domain'

These great explanations by @bpinhosilva and @ericblade also worth quoting:

client request -> web layer -> business layer -> data layer (mongoose) -> back all the way to return the data

The web server piece itself should serve solely as a layer to get data from the user, and pipe it into the application. The application shouldn't be dependent upon anything in the web server, and there shouldn't be anything tying them together, other than the point at which the data is transferred from the web server piece, into the application, and then returned to the web server client.

@bpinhosilva @ericblade You seem to have great explanation skills, we're starting soon to write our performance best practices + our boilerplate template with best practices - would love to see you join. We learn a lot by discussing, writing and coding best practices

I would be happy to contribute and discuss. I agree with you, we learn a lot by discussing.
Count on me!

@goldbergyoni
Copy link
Owner

@bpinhosilva Sounds great, expect a ping soon once we start writing. In the interim, we collect ideas here #256 - consider visiting

@goldbergyoni
Copy link
Owner

@XlintXms Any additional questions/thoughts or we can close this?

/remind me in a week

@reminders reminders bot added the reminder label Oct 2, 2018
@reminders
Copy link

reminders bot commented Oct 2, 2018

@i0natan set a reminder for Oct 9th 2018

@reminders reminders bot removed the reminder label Oct 9, 2018
@reminders
Copy link

reminders bot commented Oct 9, 2018

👋 @i0natan,

@goldbergyoni
Copy link
Owner

@XlintXms Closing this as it seems you received a satisfactory answer, feel free to comment if you wish to re-open

@HamzaAmar
Copy link

Hi @goldbergyoni @bpinhosilva I like this project so much and can i ask if this project i find in the internet is good for this repo because i dont understand it
this repo :: https://github.com/howardmann/clean-node/tree/master/models/student
this is a blog :: https://mannhowie.com/clean-architecture-node

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants