The Realm 2.0 Platform was released in October of 2017. Ian Ward presents a broad overview of useful new features and improvements to the platform.
My name is Ian Ward, and I’m an engineer on the Field Team at Realm. Today, I want to cover new features in the Realm Platform 2.0 along with the backend integration.
Today, there’s a major gap in the mobile stack. You see a lot of innovation on the client side with iOS and some of the frameworks on Android. You also see a lot of innovation on the server side, with cloud technologies such as GCP and AWS. But, in the middle, there are a smattering of different frameworks and technologies that mobile developers need to integrate with, and they tend to be pretty domain-specific. These are attached to the schema of the app, are difficult to reuse, and a lot of these frameworks are built for use in the browser and not well suited for a mobile environment.
Challenges of Mobile Development
User requirements are increasing for mobile applications:
- It needs to work offline.
- It needs to be responsive.
- It needs to have collaborative features.
This is space that the Realm Platform is playing in: The Realm Database is on the client side - it is an object database and it works completely offline, without networking. It is also reactive, so we built a notification system into the database.
Get more development news like this
The other half of the Realm Platform is the Realm Object Server. This software gets deployed on your infrastructure, in your cloud on the backend. It comes with a real-time synchronization. Any changes that happen locally on the client side or on the server side automatically get pushed across the wire.
Realm Use Cases
If you have an app that needs to work offline in the same regard that it works online with connectivity, we can deliver that out of the box. The database is always local.
Any time state changes - you do a write transaction in Realm - we automatically kickoff a sync event. We push that change across the wire immediately.
You can think about Realm as a cache. If you are loading data into the user’s Realm on a mobile device from the backend, they have that data right away. There are no loading screens, and you can rotate that data for them from the backend.
New in Realm Platform 2.0
A cross-platform Electron app, Realm Studio is a replacement for the Browser, which was only available for the Mac platform. Studio works for local Realms but it also works for the Realm Object Server.
Realm Studio monitors the Realms on the Realm Object Server. It can be your dashboard into the Realm Object Server. However, you can also use it in the same way that you used the Browser for local Realms. You can edit data and debug your code as well.
We have also introduced customization in 2.0. With npm packaging, we enabled the Realm Object Server to be a library that you can pull into your app. You can start subclassing some of the inner functionality of the Realm Object Server to build a high level of customization.
Failover and Fault Tolerance
We’ve done two major things to improve our enterprise deployment strategy for the backend.
1) We introduced the idea of synchronous backups. There are operations on the phone, operations on the master sync-worker, and operations on the backup sync-worker. The operations are how the state is changing. We don’t prune the operations off the client until the operation is both committed on the master sync-worker and the backup sync-worker.
2) We introduced Consul as our distributed key-value store to account for a master failure scenario. The master fails, then there’s a leader election, and the backup sync-worker will immediately start to serve those clients again and take over that role.
We enabled the component pieces that used to be bundled as part of Realm Object Server and split them into component services to make it stateless. The only thing that has state is the sync-worker, and that’s backed up redundantly.
Realm middlewares - the Realm auth service and Realm proxy service - can be deployed in a stateless manner and scaled out. As you start seeing CPU and memory of Realm auth increase, you can scale that out and it gets plugged into Consul. The proxy knows where to direct new auth requests to that new auth instance that you just deployed.
Built into the Realm Database is a notification callback that sends out an alert when a state has changed - insertion, modification, or deletion. We extended this functionality to the backend Realm Object Server, and you can monitor the state in all Realms on the backend Realm Object Server and then get a change callback when any state changes or when a new sync event occurs.
As an example, if I have a retail app with a coupon object and a code field associated with it, the user enters in the
coupon.code and it is saved locally.
In the background, we kick a sync event for you. There is no networking code that the developer needs to write. From there, that new sync event gets to the backend Realm Object Server.
I make a call to validate that that coupon is correct. Once I get a validate boolean back, it will save that to the Realm Object Server. From there, another sync event kicks off and transfers it back to the mobile device. That mobile device now has a valid coupon and you can have another notification that updates the UI and applies that discount.
You can see that this is how you can build a reactive mobile application stack. If you’re always reacting to state changes, this is how you can trigger API calls to your backend.
Chat App Demonstration
Here, I have a chat app on my phone and a chat app on my simulator. These two devices here are different users logged in. As I enter in different texts, they pop up immediately. You get updated in real-time.
When messages are added offline when the devices return online, they will sync and merge the different chats in the order it occurred.
This is great that they do this kind of out of the box. Normally, you have to write a lot of logic for this.
Server-side JS and .NET
Other backend servers act as another sync client. You choose what data you’re interested in and we will get that data with our sync protocol to those servers.
There are four different patterns to get data from existing APIs to put into the Realm Object Server
With Fetcher, the first two steps are analogous to how you interact with REST APIs today. I pull down on my view controller, and it sends off a request to a REST API to get the latest data.
A FetchObject that fires off a REST request and the app creates this FetchObject which syncs to the backend Realm Object Server. Then, the global notifier is configured to see that insertion and then does a GET on your web server from there. The API responds with your requested information.
The second way to GET would be to use a Poller. On the Realm Object Server, you could use
setInterval or a variety of other methods to query your API on a regular basis. If there are any changes, it will update the specific Realm.
The backend has a lot of server-side technologies that can be used in a reactive way. One of those is a messaging system called Dequeuer.
You may be familiar with a message queue like SQS on AWS or Kafka or RabbitMQ. Any time your existing API makes a change, you can enqueue that change, and the Realm Object Server - the node listener - can get that change and write it to the user’s Realm. This is a very reactive architecture.
The Data Adapter makes pre-built connectors for your database systems. It exposes the low-level instructions in Realm Core to the upper layers. They are translated into SQL commands to automatically send that data to your tables, and your schema is mapped from a Realm Object to tables in a relational database.
From there, it will automatically pull any changes that flow into Postgres, and execute Realm API commands at the appropriate Realm Objects on the Realm Object Server, and then vice versa as well.
As new sync events from the mobile client flow into the Realm Object Server, we get those low-level instructions. Things like insert, list insert, maybe even a schema change and we will execute these appropriate commands in SQL on Postgres.
About the content
This content has been published here with the express permission of the author.