How to send event to phoenix web app from core app without circular reference?

I made an umbrella project that has core app and phoenix web app.

I want to broadcast event to channel of phoenix web app when a record is created (ex. message).

core app can’t send event to phoenix web app because it doesn’t know phoenix web app.

How can I solve this problem?

One of my idea is using something like Redis.

1 Like

The usual way I’d approach the problem would be to de-couple the two things in some way, so that Core does not send events to Web, but instead publishes the events to something it knows. Like a GenEvent that’s in Core and it’s subscribers hook in from Web, or a pub/sub system (such https://github.com/phoenixframework/phoenix_pubsub or https://github.com/ostinelli/syn).

In either way, I would go with architecture where you publish events in Core and other apps can have their services listen to those events.

3 Likes

Thanks! GenEvent + PubSub will be great.

1 Like

I’m not suggesting both, pub sub is probably better option since GenEvent is sorta awkward.

2 Likes

Oh I see.

1 Like

I’ve done it like this before:

  • Create a behavior that defines the interface your Phoenix app exposes to the core app. Let’s say it has a function publish_record.
  • In your Phoenix app, create a module that implements the behavior, for instance by calling the Phoenix broadcast function.
  • In your core app, create another implementation that just calls IO.inspect, or whatever you want.
  • In the app config, store the implementation to use (i.e. the module name). You can set core to use the simulated implementation by default, and override this in your phoenix app to use the real one.
  • In core application code, retrieve the implementation module and call the function from it (mod.broadcast(...) where mod is a variable).

An alternative might be to make the core app depend on phoenix_broadcast and call its functions directly if the endpoint is running. I didn’t go that way because it made the two apps quite coupled, but YMMV!

2 Likes