Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

"The working architecture of NodeJs applications" Viktor Turskyi

267 views

Published on

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.

Published in: Software
  • Be the first to comment

  • Be the first to like this

"The working architecture of NodeJs applications" Viktor Turskyi

  1. 1. The working architecture of NodeJs applications Viktor Turskyi CEO at WebbyLab NodeUkraine 2019
  2. 2. Viktor Turskyi ● CEO and architect at WebbyLab ● 15 years in software development ● Delivered more than 60 projects of different scale
  3. 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.
  4. 4. Why we choose monolith by default?
  5. 5. The most popular architecture is...
  6. 6. Big Ball of Mud http://www.laputan.org/mud/mud.html#BigBallOfMud
  7. 7. If Monolith is a big ball of mud.
 Will it be better with Microservices?
  8. 8. Microservices: 
 Distributed big ball of mud
  9. 9. "If you cannot build a monolith what makes you think that you can build Distributed Microservices" Simon Brown
  10. 10. Microservice architecture visualized https://twitter.com/ThePracticalDev/status/845285541528719360
  11. 11. 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)
  12. 12. 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
  13. 13. 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
  14. 14. What is Monolith?
  15. 15. Usually it looks like
  16. 16. Which web-framework to choose?
  17. 17. NodeJs frameworks ● Express ● Koa ● Sails ● Nest ● Feathers ● Derby ● Kraken ● Hapi ● etc
  18. 18. It doesn’t matter!
  19. 19. Your application architecture should not depend on a web framework
  20. 20. Web frameworks we use NodeJs: Express PHP: Slim3 Perl : Mojolicious
  21. 21. MVC (from wikipedia)
  22. 22. Where to place this code? Model or Controller?
  23. 23. 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/
  24. 24. Is Model (MVC) and Domain Model the same?
  25. 25. Model (from MVC)/Domain Logic ● Domain model ● Transaction script ● Table module ● Service layer
  26. 26. Controllers Services Domain model Data access
 layer Dispatcher Layers
  27. 27. 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
  28. 28. 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)
  29. 29. 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)
  30. 30. ● 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?
  31. 31. Where do we use this architecture? ● Perl projects (Mojolicious web framework) ● PHP projects (Slim web framework) ● NodeJs (Express web framework)
  32. 32. Core patterns in the architecture Application level (Martin Fowler): ● MVC ● Service layer ● Domain model Class level (GoF): ● Template method ● Command
  33. 33. How do we cook the service layer?
  34. 34. Rule 1: Separate service class for each endpoint
  35. 35. Real code (with meta programming)
  36. 36. NodeJs example of a Service class
  37. 37. Base class (the simplest version)
  38. 38. “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.
  39. 39. Perl example of a Service class
  40. 40. 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
  41. 41. 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
  42. 42. 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/
  43. 43. 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
  44. 44. 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
  45. 45. Full example: User registration
  46. 46. User registration: controller/dispatcher
  47. 47. Controllers
  48. 48. Service
  49. 49. User model
  50. 50. Action model
  51. 51. Developers don't have to be full-stack but teams should be. https://martinfowler.com/bliki/PresentationDomainDataLayering.html
  52. 52. 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
  53. 53. 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
  54. 54. Telegram: @JABASCRIPT
  55. 55. Viktor Turskyi viktor@webbylab.com @koorchik @koorchik https://webbylab.com

×