In their Phoenix LiveView course (which is excellent!), the Pragmatic Studio guys define a function in a Phoenix context, LiveViewStudio.Volunteers.broadcast/2
, like this:
def broadcast({:ok, volunteer}, event) do
Phoenix.PubSub.broadcast(
LiveViewStudio.PubSub,
"volunteers",
{event, volunteer}
)
{:ok, volunteer}
end
… which they then append to the write functions for that Phoenix context, as with LiveViewStudio.Volunteers.update_volunteer/2
:
def update_volunteer(%Volunteer{} = volunteer, attrs) do
volunteer
|> Volunteer.changeset(attrs)
|> Repo.update()
|> broadcast(:volunteer_updated)
end
… which they use to implement real-time updates in a LiveView
; and this general pattern strikes me as preferable to the absinthe
way of doing things, which is to use a Absinthe.Schema.Notation.trigger/2
macro, because the message is sent every time the context function is invoked, rather than ‘just’ when a GraphQL
mutation is run.
I would like to continue giving PubSub messages to both the GraphQL
subscription and to the LiveView
, and I would also like for each to catch events given to the other; I think that I can add an additional call to Absinthe.Subscription.publish/3
to the aforementioned LiveViewStudio.Volunteers.broadcast/2
function, like this:
def broadcast({:ok, volunteer}, event) do
Phoenix.PubSub.broadcast(
LiveViewStudio.PubSub,
"volunteers",
{event, volunteer}
)
Absinthe.Subscription.publish(
LiveViewStudioWeb.Endpoint,
volunteer,
change_volunteers: "volunteers"
)
{:ok, volunteer}
end
It seems like absinthe
shards the topics you give it (to avoid collision?), but it seems like it would maybe be better if I could just give the ‘naked’ topic to Absinthe.Schema.Notation.config/1
, rather than sending out two different messages. Is that possible, or am I ‘stuck’ sending two events?