I've seen a lot of NodeJs applications. I see a lot of misunderstandings around architectural patterns. 99% of NodeJS tutorials do not cover this topic and limited to "hello world" apps. How to build a really large application? How to think about architectural layers? What is wrong with the majority of JS frameworks? How does GraphQL influence my architecture? I will answer all of these questions.
2. Viktor Turskyi
● CEO and architect at WebbyLab
● 15 years in software development
● Delivered more than 60 projects of
different scale
3. I want to talk about
● The approach which we polish for 8 years already
● How to build large and small web applications with it
● How we use the same architecture for NodeJs, PHP, Perl web application
● Why we choose Monolith over Microservices first.
● Show real code, not only diagrams.
● What framework to choose.
● How all of it saves us money.
13. Microservices drawbacks
● High operational complexity (increases costs)
● Extremely hard to support transactions (risks of inconsistencies)
● Distribution issues (harder to program)
● Traceability issues (harder to debug)
● Technology diversity (mixing languages increases support costs,
standardization issues, hiring issues etc)
● Versions compatibility issues (harder to track all dependencies in consistent
state, reduces iterations speed)
● You need more experienced team (hiring issues)
14. Martin Fowler:
● But when your components are services with remote communications, then
refactoring is much harder than with in-process libraries.
● Another issue is If the components do not compose cleanly, then all you are
doing is shifting complexity from inside a component to the connections
between components. Not just does this just move complexity around, it
moves it to a place that's less explicit and harder to control.
https://martinfowler.com/bliki/MonolithFirst.html
15. Robert Martin:
“The job of architect is not to make decision, the job of the architect is to
defer decisions as long as possible”
“Good architecture maximizes number of decisions not made”
https://www.youtube.com/watch?v=o_TH-Y78tt4
26. Fat Stupid Ugly Controllers
“The M in MVC: Why Models are Misunderstood and Unappreciated” Pádraic
Brady
http://blog.astrumfutura.com/2008/12/the-m-in-mvc-why-models-are-
misunderstood-and-unappreciated/
31. The way of thinking about Controllers
● Extremely thin layer
● Protects underneath layers from everything related to HTTP
● If you change JSON to XML (or even CLI), only controllers should be
rewritten
32. The way of thinking about Domain Model
● Belongs to Model layer of MVC
● The core part of your application
● You have almost all of your business logic here (not only database access)!!!
● Knows nothing about service layer and upper layers
● Responsible for data storing and data integrity
● Fine grained API (not suited for remote invocation)
33. The way of thinking about Services
● Belongs to Model layer of MVC
● Contains application logic
● Does not trust any incoming params
● You should keep thin if possible
● Knows nothing about controllers/transport/UI.
● Use cases based API
● Knows about context (what user asks for data)
● Knows when and how to notify user (emails etc)
● Does coordination and security
● Coarse grained API (well suited for remote invocation)
34. ● Web framework independent layer of domain logic
● Learn once, write everywhere
● Well structured
● Works with large and small projects
● Hard to find existing framework which does the the same work.
Why own architecture?
35. Where do we use this architecture?
● Perl projects (Mojolicious web framework)
● PHP projects (Slim web framework)
● NodeJs (Express web framework)
36. Core patterns in the architecture
Application level (Martin Fowler):
● MVC
● Service layer
● Domain model
Class level (GoF):
● Template method
● Command
43. “run” method
Template method in base class
Guarantees that all procedures are kept:
● Data was validated
● “execute” will be called only after validation
● “execute” will receive only clean data
● Checks permissions before calling “execute”
● Throws exception in case of validation errors.
Can do extra work like caching validator objects, etc.
47. Rule 2: There is no excuse for not using Promises or await/async today
● Error handling - one of the most powerful promise features. You can structure
your error processing in a much better way with promises.
● You will never see “uncaughtException”
● You will have manageable code
48. Rule 3: Unified approach to validation
● DO NOT TRUST ANY USER INPUT! NEVER!!!
● Declarative validation
● Exclude all fields that do not have validation rules described
● Returns understandable error codes (neither error messages nor numeric
codes)
● It should be clear for the service user what is wrong with his data
49. We use LIVR for the validation
It supports:
● JavaScript
● Perl
● Perl 6
● PHP
● Go
● Erlang
● Python
● Ruby
● Java
● Lua
Details are here - http://livr-spec.org/
50. Rule 4: Never return objects directly
Whitelist every object
property:
1. You know what you
return (that no internal/
secret data there)
2. Your API is stable
51. It should be clear where any code should be! Otherwise you do not architecture.
One of the risks, than you can end up with an “Anemic domain model” (https://
www.martinfowler.com/bliki/AnemicDomainModel.html)
If you have a large project, this can be a reason of project failure as you will
implicitly switch to “transaction script” approach which is not well suited for large
applications.
Rule 5: Be aware of “Anemic domain model” antipattern
61. Developers don't have to be full-stack but teams should be.
https://martinfowler.com/bliki/PresentationDomainDataLayering.html
62. Main benefits
● NodeJs, PHP, Perl - the same architecture.
● Works with small and large projects
● Extremely flexible.
● Ease to start.
● Much cheaper for company to support the same approach on all projects.
● Web framework agnostic and based on micro frameworks which is easy to
learn for new person.
● Cheaper technology switch (for example from PHP to NodeJs).
● Cheaper communication.
● Knowledge sharing (larger core).
● Higher resources utilization.
● Monolith first approach and modular architecture allows us to switch to
Microservices later
63. Useful links
MonolithFirst by Martin Fowler
Microservice Trade-Offs by Martin Fowler
PresentationDomainDataLayering by Martin Fowler
The Principles of Clean Architecture by Uncle Bob Martin
The Clean Architecture by Robert Martin
Microservice Architecture at Medium