3 ms·
I agree 100% on avoiding the "magic". Particularly since implementing DI in frameworks like express/koa is already drop dead simple - literally just have your
by horsawlarway 5y ago
I agree 100% on avoiding the "magic".
Particularly since implementing DI in frameworks like express/koa is already drop dead simple - literally just have your first middleware add your services to the request context (Side note - this works just fine with TS, including nice auto-complete and type-hinting).
- rektide 5y agoAs someone whose walked through a lot of code-bases, I rather hate the "unmagic" just-write-whatever-nest-of-route.js-files-you-want path. It's easy to write routes in express, yes. But every company & usually every project in the company usually does it differently. Oh this person used a glob tool to find all the route.js files. Oh this person has nested route.js files littered about. Oh this project is just a massive ultra-complicated routes.js. A huge part of the win of DI & places like Java JAX-RS is that code one place looks fairly alike code another place. Dependency Injection frees us from having to know a project well, from having to be familiar with structure; we simply ask or tell, & there's a system there. I find it elegant that Express routing concerns, React concerns, and all the various configuration/providing systems you might need can be managed via IoC. Recent TypeScript example I found of these concerns, in Injex: https://www.injex.dev/docs/plugins/express#get-post-patch-put-del https://www.injex.dev/docs/plugins/express#get-post-patch-pu... https://www.injex.dev/docs/plugins/react#the-renderinjexprovider-method https://www.injex.dev/docs/plugins/react#the-renderinjexprov... There's a lot of push back against "magic", but really I think it's something that served Java extremely fantastically well, particularly the Dependency Injection/IoC systems. I think developers of those systems got a ton of value, and it was really understated just how noble & simple those worlds were, how clean & easy it was to walk up to any random controller & be able to discern more or less what data was going to get used, in what scopes. By not having all that stuff written in the ad-hoc, existentially open world of declarative code, and instead encoded as normative, regularized, low-overhead annotations, there was a kind of predictability & visualizability & simplicity that I think a lot of these practitioners probably sorely miss, now that they're probably mostly writing Node.js like nearly everyone else. ;)
- twistedpair 5y agoWith great power comes great responsibility. I've seen Spring projects where DI was a total rat nest of hundreds of XML wireup config files. Downhill with a tailwind, it just might boot correctly, after minutes classpath scanning for dependencies. Use DI judiciously where it provides the most value. Type, if you can type it (e.g. I vastly prefer explicit wireup in Guice Module.java files over Spring's "stringly typed" XML files. Type checking is more likely to catch classpath errors and typos. Event better, use compile time macro wireup like Scala's Macwire.
- rektide 5y agoIn the manage your objects/entities vs don't manage your objects entities (just code) struggle, I strongly advise the opposite for most folk: figure out better containerizations of control for your entities/objects. There's plenty of bad examples of ALL good & popular technologies. Don't be afraid, don't believe the terror being sold to you: give it a go, explore, see what value there is.
- eyelidlessness 5y agoI don’t like to reply to an agreement with a disagreement, but I find Express-style middleware exactly the kind of magic and type-safety defeating stuff I prefer to avoid. You can surely make it safer and more explicit by, for instance, creating a new wrapper for your Router or whatever. But by default the interface promotes casting/coercion of Request etc and just blindly asserting that you’re sure the middleware you’re expecting is attached. In the past, I’ve worked around this by wrapping Express to make any middleware dependencies explicit on each route, and by making “middleware” actually just pure functions which return whatever state they derived from the Request. Essentially a Route just becomes a pipeline of composable functions. It worked very well, but in hindsight I found I got almost no value out of Express itself at that point.