Resulting context
The primary benefit of this solution is that it provides extremely high availability and responsiveness for important user interactions. Users perceive the system as responsive and available even when connectivity is intermittent. The data is stored and accessed locally, thus it is always available when needed and the load on backend resources is reduced. The data has the potential to be stale when connectivity is intermittent, but that is the best alternative among bad alternatives. When connectivity is restored, the data is synchronized with the cloud storage and ultimately across devices, creating a resilient solution.
It is important to be upfront with the user about the eventual consistency of the data. Some solutions strive to be completely transparent, such that the user would not know the difference between being connected and not. This may be reasonable for certain applications, but most have diminished capabilities when disconnected. For example, an e-commerce app could show your recent history when disconnected but not allow for the execution of new searches. Therefore, it is important to provide clues to the user about the accuracy of the cached data. For example, a visible as of timestamp may accompany data in a materialized view or a pending status may be provided for outgoing actions. We all experience this kind of functionality in the email applications on our smartphones every day. This approach lends itself best to user-specific data such as preferences or work in progress like a shopping cart or a draft document, and transaction status information such as the status of an order or a review process. It is important to all parties that the data is not lost.
This solution is essentially a client-side extension to the Event Sourcing and CQRS patterns. User actions are stored on the client-side using Database-First Event Sourcing and the changes are eventually synchronized to cloud storage where the cloud-side CDC mechanism triggers the logic to publish a domain event downstream. Materialized views are created just as we discussed in the CQRS pattern, only the view is stored in the cloud storage of the offline-first database and eventually synchronized to the devices.
An interesting aspect of this solution is that there is no need to implement a synchronous interface for the component. The synchronous interface is provided by the fully managed third-party service and only needs to be configured. On the client-side, an SDK is used to access the API and hide many of the details, such as the security model. Examples of these services include GCP Firebase and AWS Cognito.