Is there a technical or philosophical difference between using one or the other ?
I end up using both in my code without understanding why.
Any help appreciated.
Nearly a year later, but I’ve wondered about this also - why does Phoenix.Endpoint have all those delegated functions in its
__using__ macro? It seems more transparent to me to just use the configured PubSub explicitly. Any thoughts?
[Aside: the stuff obscured, albeit shallowly, in
__using__ is one of the few things so far I’m sometimes dubious about in Elixir/Phoenix. Shades of superclasses (OK, only distant shades). OTOH as one of the means by which Phoenix in particular scaffolds you when starting out, it’s clearly part of the productivity story. But it does give me the odd qualm.]
PubSub sends any message. Phoenix.Endpoint and channels send phoenix specific messages and enable fast laneing to limit the number of encodings one does when sending to multiple socket listeners. It‘s not just some shallow shadowing of API.
The Phoenix.Endpoint subscribe looks like simple delegation to me:
def subscribe(topic, opts \\ ) when is_binary(topic) do
Phoenix.PubSub.subscribe(pubsub_server!(), topic, opts)
Of the whole “pubsub” based api on the endpoint (8 funs) two happen to be mostly delegations. That’s what I consider “providing a complete api” instead of requiring users of channels to not only know how to fetch the pubsub module on their own, but also to look in multiple places for functionality, which is supposed to be one cohesive set. (Also removing API would need deprecation or even a major version release)
Phoenix channels align very much with pubsub api wise – which makes sense given pubsub was extracted out of the channels codebase – but it’s still a subset of pubsub in that it has some additional constraints around how messages need to look like and which information is provided by those messages for channels/sockets to be able to pick them up. Also as mentioned theres the fastlaneing optimizations.
That does affect even subscribing. If you use
Phoenix.Endpoint.subscribe it’s reasonable to expect to receive only messages, which adhere to the format mentioned. If you subscribe with
Phoenix.PubSub that assumption is off.
Plain Phoenix.PubSub is more low level than the channels based messaging.
Thanks @LostKobrakai, that seems like a good explanation of the (apparently shallow)
subscribe delegation, when put in the overall higher-level API context. I didn’t know there was a distinction between channel-based broadcasts and whatever more generic thing it is that PubSub is doing (I’m still new to Elixir/Phoenix). One more thing to read up on at some point.
Seing only today that there has been a follow-up on my question. Sorry for not tagging the answer earlier.