In designing an API to avoid import cycles, I have one of two options structure wise, and I'm not sure which one is a better choice, as each have pros and cons.
Background
I'm only describing the two inter-related packages here, as those which are well encapsulated aren't an issue. There is a user package that contains all the data that we store on a per user basis, as well as all the functions and HTTP handlers that are performed on any user. There is also a message package that contains the structures and functions that are needed when one user sends a message to another user, or when system messages are sent to a user. The message package also contains sub-packages for different push notification types (e.g. Google Cloud Messaging, Apple Push Notifications, etc.).
The import cycle problem is that sometimes when a message is sent, to a user, the result from the push notification server may state that the push notification settings for that user need to be changed. But at the same time, some functions that may be performed on a user may trigger a message to a different user.
Solution 1
Include the code in the message package as part of the user package. The downside here is that it makes the user package even bigger than it currently is, and somehow feels like it's more entangled than it needs to be.
Solution 2
Have some base package that has all the HTTP handlers in it, which can import both the user and message packages and hence can perform actions on both of them. The downside to this is that all the handlers would only be able to use exported functions, and so there would be more exported functions than there currently are.
Is there a well proven best practice to handle this situation in Go?