[HN Gopher] Tao of Node - Design, Architecture and Best Practices
___________________________________________________________________
Tao of Node - Design, Architecture and Best Practices
Author : kiyanwang
Score : 100 points
Date : 2022-03-27 09:24 UTC (13 hours ago)
(HTM) web link (alexkondov.com)
(TXT) w3m dump (alexkondov.com)
| Morzaram wrote:
| Wow this is so well written. I've been struggling with finding a
| method of organizing code and things. Coming from a rails
| environment I struggled finding a layout that wouldn't easily
| turn to spaghetti.
|
| Thank you for taking the time and writing this!
| jackblemming wrote:
| This is good stuff, but very little of it is specific to node.
| It's more of Tao of Web APIs that happens to use node as the
| example language.
| yangcheng wrote:
| Agree, I find most of the content applies to my golang services
| lelandfe wrote:
| I'm going to need to read through this a few times to give my
| thoughts on the opinions but I have to say:
|
| Thank you for providing code examples of both what not and what
| _to_ do. So many of these architectural principle articles just
| stay floaty and academic instead of having practical examples.
| dyeje wrote:
| This reminds me of that Python / Django (can't recall)
| architecture guide posted a while back. Most of it is just
| generally good advice for web service architecture, regardless of
| language or framework. The tooling section here gets more into
| preference territory though.
| stochastastic wrote:
| This guide?
|
| https://alexkrupp.typepad.com/sensemaking/2021/06/django-for...
| sagarjs wrote:
| This is a great resource. I have come to the same conclusions
| after years of coding web apis and it's very helpful to have it
| written down.
| ErikAugust wrote:
| "To this day, it's hard to find two Node applications that are
| structured similarly."
|
| I've seen a few Express applications that were mostly the same.
| BiteCode_dev wrote:
| With auth, perms, db setup, templating, validation and
| migrations ?
| ivailop wrote:
| Great work, Alex!
| yes_but_no wrote:
| Great article. I also suggest watching Casey M. recent video[0]
| about Conways Law. How organization in your company determines
| what you can/will do and how organization of your code follows
| the same principles.
|
| Starting with just the handlers and introducing layers as you
| make sure its time is great way.
|
| [0]https://www.youtube.com/watch?v=5IUj1EZwpJY
| fatbird wrote:
| This is a digression, but the book starts by saying that it's a
| benefit to the developer to have one language front and backend.
| I've been working on node/JS web apps for several years now, so
| this is my lived reality, but I _don 't_ like that it's the same
| language front and backend. Just as a web page with HTML,
| JavaScript and CSS lets me mentally separate the different
| aspects of the front end and context switch more easily between
| them (I'm never confused about what I'm addressing), I've found
| having JS both front and back end (separated by a GraphQL API) to
| require being more conscious of my environment. There are subtle
| differences between Node and the browser VM; there are different
| concerns with resource usage and concurrent operations.
|
| When doing React I refused to follow Facebook's lead and relocate
| styles into the code. In my mind it just crowded the JavaScript
| and made for more code where multiple concerns where colocated.
| Am I the only one who felt this way?
| cies wrote:
| > the book starts by saying that it's a benefit to the
| developer to have one language front and backend
|
| I also cringed at that premise. JS sucks a lot, having it on
| both sides would make things worse. Yes TS can help here, but
| only so much. You cannot make up for a languages design
| mistakes by bolting on a type system. Also: making a SPA-like
| browser app makes thing think about the state of the
| application twice! This comes at huge cost. Simple page-to-page
| applications with SSR are waaaay easier to build an maintain.
|
| When I do browser apps I prefer a strong-typed API spec from
| which I generate (1) client libs and (2) server stubs. This
| gives me some safety guarantees over the API barrier.
|
| Using a language like Elm with an "elm-graphql" generated
| client lib is a bliss. Compile gQL queries in a type safe
| manner: if it compiles it runs. I feel there is soo much more
| "tao" (simplicity, peace of mind, zen, less moving parts) in
| this approach than in the JS-article I just read.
| Madeindjs wrote:
| This is a really great resource. All of theses tips are
| implemented in Nest.js framework. I can't recommend enough to
| give it a try, it'll force you yo have best practices.
| qxqdtqutwtv wrote:
| This was really great and closely matches how we do it as well.
|
| For people who generally follow this approach, what's your take
| on structured logging transaction traces, or more generally,
| propagating request-contextual information through the call
| stack? TFA seems to prefer a res.locals approach, but it's
| coupled to the framework in a way that the article avoids
| elsewhere, and needs manual propagation beyond the express
| handoff. I've seen these alternatives:
|
| One team in my organization uses explicit context objets that get
| passed to every function call as the first argument, in a style
| very similar to what is idiomatic in Golang. I find this to be
| viral and not to compose well with third-party code that ends up
| calling your own code, which is rare with npm modules but
| somewhat common with company-internal libraries.
|
| Another team was an early adopter of node async hooks to create
| the equivalent of a continuation local storage, with cls-hooked
| at around the time of node 8. They reported several problems that
| were implementation related, but seemed to prefer the developer
| experience of the approach, and context was preserved through
| third party code just fine. E: (Apparently this now ships
| standard in node with AsyncLocalStorage)
| mrloba wrote:
| Very nice, I found myself nodding along with almost everything in
| this post. One thing I do a bit differently is that I usually put
| the API handlers in their own module (they're usually just a
| couple lines of code each), along with domain-to-api model
| transformers. This is because I often have various worker entry
| points as well, and it's nice to keep the domain logic separate
| from all the different entry points. I also like to keep all
| routes in a single file. I don't like to hunt down the full route
| path across a bunch of different files, and I like to be able to
| get a full overview of the API in one place. Just different
| tradeoffs I guess
| zelphirkalt wrote:
| > It grew from a questionable technology to one used for critical
| infrastructure in many large enterprises. It performs incredibly
| well for high-volume IO operations with a much lower code
| complexity than languages that rely on multi-threading.
|
| Well, that is not where one usually uses multi-threading (OS
| level threads), as the threads would possibly be bottle-necked by
| IO and there would be no use of having the overhead of multiple
| threads. IO does not become magically faster by using multiple
| threads.
|
| Which languages "rely" on doing that? Many popular languages have
| green threads and many have asynchronous concepts. I would
| assume, that programming language designers are aware and do not
| prescribe using multiple threads for IO of multiple concurrent
| "execution units".
|
| Note: Little typo in the TOC: "Cetralize error handling".
| morelisp wrote:
| The complete failure of early Java iterations of green threads
| and fall back to 1:1 OS threads, along with terrible async
| ergonomics in Java, meant a lot of backend software was based
| on real OS thread e.g. per connection. The story was similar in
| C/C++ for different reasons - the details of select and its
| various extensions were some of the least portable parts of
| otherwise POSIX interfaces. And on the lower end e.g. Python
| also relied on OS threads unless you built your entire
| application around one of the early async reactors.
|
| The real success story behind node is libuv. It's a shame it
| was married to such a mediocre language, but that language did
| have some of the least-bad async ergonomics at the time (nearly
| by accident - client-side JS _had to_ yield to the browser
| frequently, and the language was mostly designed to run small
| code blocks instead of application lifecycles).
| erikpukinskis wrote:
| The author is saying "green threads" and "asynchronous
| concepts" are more complex than "everything is synchronous".
| is0tope wrote:
| This was a great read! I've been using node on and off for
| personal projects for some time, and also always hated the fact
| that it was very unclear how you should structure a project. At
| least with django, it was clear. This provided a really nice set
| of techniques that I will be sure to put to use. Thanks!
| deltaonefour wrote:
| The tao of node?
|
| It reminds me of this story about a secretive master kung fu
| artist who perfected his technique but taught his style to no
| one. Yet the master still wanted to document his style in a kung
| fu manual. So he did, but as a security measure, he wrote
| everything backwards so that anyone reading it would get the
| wrong set of instructions. If a move involved a user blocking a
| hit with his arm he would write down that the hit should be
| blocked with his foot. Every move was a complete reversal of what
| should be done.
|
| One day a thief stole the kung fu manual with the goal of reading
| it and becoming a great kung fu master. The thief read the manual
| day and knight and practiced just as much. And guess what? the
| thief became an incredible master surpassing the original author
| himself. Nobody could figure out his hilarious style, when you
| tried to punch him in his face his foot would immediately come up
| to deflect the punch. Everyone was WTF? How does this shit work?
| The thief ended up founding a kung fu school and taught everyone
| this style... proliferating the backwards art all across China,
| much like the same way Node has proliferated across the world.
|
| I made the last part up because I thought it would be a more apt
| analogy. What actually happened is the thief went crazy because
| the the backward moves caused his chi to spin in the opposite
| direction... driving him insane. Anyway, this is what the Tao of
| Node reminds me of. I should also say so does the Tao of CSS and
| HTML and maybe the Tao of the entire web reminds me of this
| story.
|
| Do these things really need to be associated with Tao as if it's
| some great art or philosophy? Feels a bit pretentious, but that's
| just me.
| lmeyerov wrote:
| We have generally followed that for years, this is great! A few
| big missing areas:
|
| - node is also often the best for - 'backend for your frontend' (
| batching/caching, ...) which adds a bit more complexity
|
| - structured logging should really be tracing given the heavy
| async + services nowadays
|
| - This architecture is normally done as part of some scalable m:n
| mapping, which is alluded to, but can be a full article to itself
| (tools, patterns, manual/auto operations, ..)
|
| We have been moving Graphistry's regular stateless web backends
| to python as it converges with node on async but is easier to do
| our GPU + AI data services (and other reasons).. but been
| generally keeping our 'backend for the frontend' parts here. This
| could have been part of a primer in our internal docs, so bravo!
___________________________________________________________________
(page generated 2022-03-27 23:01 UTC)