xmppjs / xmpp.js

XMPP for JavaScript
ISC License
2.19k stars 373 forks source link

Adopt junction middleware #439

Open smokku opened 7 years ago

smokku commented 7 years ago

@sonnyp mentioned in some comment, that we would like to have a stanza routing middleware, to handle application-lever stanza routing.

What about adopting https://github.com/jaredhanson/junction ? It has an extensive set of plugins, both bundled and stand-alone. It has a nice, express.js inspired stanza handling model.

I use it in both my XMPP client application, and also in XMPP server implementation and it works great.

I already ported it for new xmpp.js changes: https://github.com/smokku/junction

@jaredhanson what do you think? Your repo looks dormant. It would be a shame to let this nice code slip to oblivion.

sonnyp commented 7 years ago

Crazy I've never heard of junction before.

We're already using js-sasl from @jaredhanson (thanks!) :)

@smokku perfect timing, I was looking today at our current plugin API and how to tweak it to for server usage as well so I started hacking a connect like API.

Wether we port junction or adopt a similar API, it is gonna require some work though and I'd like to release 1.0 ASAP as more and more people are getting confused about the rewrite/rename and the current state.

So 👍, let's go back to this after 1.0 release. Meanwhile, I'm wondering how well this API plays client side, any thoughts?

smokku commented 7 years ago

Sure. 1.0 shouldn't wait for it.

I like junction very much. I especially love, how little you have to do, to handle unhandled stanzas - i.e. IQs that require response. You just put junction.serviceUnavailable() at the end of the chain and it will respond with service-unavailable to every stanza that wasn't handled before. Also junction.errorHandler() middleware simplifies all error handling to the point you don't really have to think about it anymore. Just throw an Error (or leave uncaught) in any middleware, and it will turn out as a proper error stanza response to the sender. No brainer. :)

smokku commented 7 years ago

In my server implementation I have three separate Junction chains handling packets incoming to clients, packets incoming to server instance and outgoing packets sent by clients. Each have very different characteristics of how it needs to process stanzas, yet some elements ale common. Junction allows me to implement XEP support just by adding new middleware in a proper order.

This use case is enabled by clear separation of junction stack and node-xmpp incoming stanza handling. You can hook Junction to any emitter emitting stanzas. Or even inject stanzas manually (with some pre-processing).

smokku commented 7 years ago

BTW, If we decide to port Junction I could do it. I already forked it and know my way around it.

It would be nice to have green light from @jaredhanson though. :-)

sonnyp commented 6 years ago

https://github.com/xmppjs/xmpp.js/pull/490

sonnyp commented 6 years ago

we now have a junction inspired middleware API

smokku commented 6 years ago

There is one, crucial thing missing in the current middleware implementation compared tu Junction - automatic error handling.

Junction handler can throw or pass an Error instead of packet, and this will get converted to an error response (if the processed stanza is of type requiring/supporting response). See errorHandler.js

This makes error handling&responding close to trivial. If you detect a problem with the processed stanza, just instanitate StanzaError and reject a promie, or just throw it and let errorHandler craft proper response.

Also, when there is an error in your code, the internal-server-error is for free. Technically, junction middleware wraps every handler call in try/catch and when uncaught error leaves the handler, it automatically passes the error to the next() handler as err parameter.