# A Practical Exercise of Atlas Device SDK for Web With Sync (Preview)

**Table of contents** 
* Atlas Device SDK for web with Device Sync and its real-world usage 
* Architecture 
* Basic components
* Building your own React web app 
   - Step 1: Setting up the back end
   - Step 2: Creating an App Services app 
   - Step 3: Getting ready for Device Sync 
   - Step 4: Atlas Device SDK
   - Step 5: Let the data flow (start using sync)!
* Implementation of the coffee app
* A comparison between Device Sync and the Web SDK without Sync
   - What will our web app look like without Device Sync?
   - Which one should we choose?
* Conclusions
* Appendix 

## Atlas Device SDK for web with Sync and its real-world usage

The Device Sync feature of the Web SDK is a powerful tool designed to bring real-time data synchronization and automatic conflict resolution capabilities to cross-platform applications, seamlessly bridging the gap between users’ back ends and client-side data. It facilitates the creation of dynamic user experiences by ensuring eventual data consistency across client apps with syncing and conflict resolution.

In the real-world environment, certain client apps benefit from a high level of automation, therefore bringing users an intuitive interaction with the client app. For example, a coffee consumption counter web app that allows the user to keep track of the cups of coffee he/she consumes from different devices and dynamically calculates daily coffee intake will create a ubiquitous user experience.

In this tutorial, I will demonstrate how a developer can easily enable Device Sync to the above-mentioned coffee consumption web app. By the end of this article, you will be able to build a React web app that first syncs the cups of coffee you consumed during the day with MongoDB Atlas, then syncs the same data to different devices running the app. However, our journey doesn’t stop here. I will also showcase the difference between the aforementioned Web SDK with Sync (preview) and the Web SDK without automatic syncing when our app needs to sync data with the MongoDB back end. Hopefully, this article will also help you to make a choice between these two options.

## Architecture

In this tutorial, we will create two web apps with the same theme: a coffee consumption calculator. The web app that benefits from Device Sync will be named `Coffee app Device Sync` while the one following the traditional MongoDB client will be named `Coffee app`.  

The coffee app with Device Sync utilizes Atlas Device Sync to synchronize data between the client app and backend server in real time whilst our coffee app without Device Sync relies on the MongoDB driver. 

Data synchronization relies on the components below.

 1. _App Services_: App Services and its Atlas Device SDKs are a suite of development tools optimized for cross-platform devices such as mobile, IoT, and edge, to manage data via MongoDB’s edge database called Realm, which in turn leverages Device Sync. With various SDKs designed for different platforms, Realm enables the possibility of building data-driven applications for multiple mobile devices. The Web SDK we are going to explore in this article is one of the handy tools that help developers build intuitive web app experiences. 
 2. _User authentication_: Before setting up Device Sync, we will need to authenticate a user. In our particular case, for the sake of simplicity, the `anonymous` method is being used. This procedure allows the sync from the client app to be associated with a specific user account on your backend App Services app.
 3. _Schema_: You can see schema as the description of how your data looks, or a data model. Schema exists both in your client app’s code and App Services’ UI. You will need to provide the name of it within the configuration. 
 4. _Sync configuration_: It is mandatory to provide the authenticated user, sync mode (flexible: true), and `initialSubscriptions` which defines a function that sets up initial subscriptions when Realm is opened.
 5. _Opening a synced realm_: As you will see, we use `Realm.open(config);` to open a realm that is synchronized with Atlas. The whole process between your client app and back end, as you may have guessed, is bridged by Device Sync. 

Once Realm is opened with the configuration we discussed above, any changes to the coffee objects in the local realm are _automatically_ synchronized with Atlas. Likewise, changes made in Atlas are synchronized back to the local realm, keeping the data up-to-date across devices and the server. What’s even better is that the process of data synchronization happens seamlessly in the background without any user action involved.

)

Back end:
* MongoDB Atlas, as the cloud storage
* Data (in this article, we will use dummy data)
* MongoDB App Services app, as the web app’s business logic

These components briefly describe the building blocks of a web app powered by MongoDB App Services. The coffee app is just an example to showcase how Device Sync works and the possibilities for developers to build more complicated apps. 

## Building your own React web app

In this section, I will provide step-by-step instructions on how to build your own copy of Coffee App. By the end, you will be able to interact with Realm and Device Sync on your own. 

### Step 1. Setting up the back end

MongoDB Atlas is used as the backend server of the web app. Essentially, Atlas has different tiers, from M0 to M700, which represent the difference in storage size, cloud server performance, and limitations from low to high. For more details on this topic, kindly refer to our documentation.

In this tutorial, we will use the free tier (M0), as it is just powerful enough for learning purposes. 

To set up an M0 cluster, you will first need to create an account with MongoDB. 

Once the account is ready, we can proceed to “Create a Project.” 

 as this will not be in the scope of this article.

### Step 2. Creating an App Services app

App Services (previously named Realm) is a suite of cloud-based tools (i.e., serverless functions, Device Sync, user management, rules) designed to streamline app development with Atlas. In other words, Atlas works as the datasource for App Services. 

Our coffee app will utilize App Services in such a way that the back end will provide data sync among client apps. 

For this tutorial, we just need to create an empty app. You can easily do so by skipping any template recommendations. 

 gives a very good explanation of why schema is a mandatory and important component of Device Sync: 

_To use Atlas Device Sync, you must define your data model in two formats:_

* _**App Services schema**: This is a server-side schema that defines your data in BSON. Device Sync uses the App Services schema to convert your data to MongoDB documents, enforce validation, and synchronize data between client devices and Atlas._
* _**Realm object schema**: This is client-side schema of data defined using the Realm SDKs. Each Realm SDK defines the Realm object schema in its own language-specific way. The Realm SDKs use this schema to store data in the Realm database and synchronize data with Device Sync._

> Note: As you can see, Development Mode allows your client app to define a schema and have it automatically reflected server-side. (Simply speaking, schema on your server will be modified by the client app.) 

As you probably already guessed, this has the potential to mess with your app’s schema and cause serious issues (i.e., stopping Device Sync) in the production environment. 

We only use Development Mode for learning purposes and a development environment, hence the name.

By now, we have created an App Services app and configured it to be ready for our coffee app project.

### Step 3. Getting ready for Device Sync

We are now ready to implement Device Sync in the coffee app. Sync happens when the following requirements are satisfied.

* Client devices are connected to the network and have an established connection to the server.
* The client has data to sync with the server and it initiates a sync session. 
* The client sends IDENT messages to the server. *You can see IDENT messages as an identifier that the client uses to tell the server exactly what Realm file it needs to sync and the status of the client realm (i.e., if the current version is the client realm’s most recently synced server version). 

The roadmap below shows the workflow of a web app with the Device Sync feature. 

 and MongoDB Atlas Device SDK for the coffee app in this article. 
 
Despite the differences in programming languages and functionalities, SDKs share the following common points:

Despite the differences in programming languages and functionalities, SDKs share the following common points:
* Providing a core database API for creating and working with local databases
* Providing an API that you need to connect to an Atlas App Services server, and therefore, server-side features like Device Sync, functions, triggers, and authentication will be available at your disposal 

We will be using Atlas Device SDK for web later. 

### Step 5. Let the data flow

**Implementation**:

Without further ado, I will walk you through the process of creating the coffee app.

Our work here is concentrated on the following parts:

* App.css — adjusts everything about UI style, color
* App.js — authentication, data model, business logic, and Sync
* Footer.js. — add optional information about the developer
* index.css. — add fonts and web page styling

As mentioned previously, React will be used as the library for our web app. Below are some options you can follow to create the project. 

As mentioned previously, React will be used as the library for our web app. Below are some options you can follow to create the project. 

**Option 1 (the old-fashioned way)**: Create React App (CRA) has always been an “official” way to start a React project. However, it is no longer recommended in the React documents. The coffee app was originally developed using CRA. However, if you are coming from the older set-up or just wish to see how Device Sync is implemented within a React app, this will still be fine to follow. 

**Option 2**: Vite addresses a major issue with CRA, the cumbersome dependency size, by introducing dependency pre-bundling. It provides lightning-fast, cold-starting performance. 

If you already have your project built using CRA, there is also a fast way to make it Vite-compatible by using the code below. 

`npx nx@latest init`

The line above will automatically detect your project’s dependency and structure and make it compatible with Vite. Your application will therefore also enjoy the high performance brought by Vite. 

Our simple example app has most of its functionality within the `App.js` file. Therefore, let’s focus on this one and dive into the details. 

(1)
Dependency-wise, below are the necessary `imports`. 

```
    import React, { useEffect, useState } from 'react';
import Realm, { App } from 'realm';
import './App.css';
import Footer from './Footer';
```

Notice `realm` is being imported above as we need to do this to the source files where we need to interact with the database. 

(Consider using the `@realm/react` package to leverage hooks and providers for opening realms and managing the data. Refer to MongoDB’s other Web Sync Preview example app for how to integrate @realm/react.)

(2)

```
    const REALM_APP_ID = 'mycoffeemenu-hflty'; // Input APP ID here.
const app = new App({ id: REALM_APP_ID });
```

To link your client app to an App Services app, you will need to supply the App ID within the code. The App ID is a unique identifier for each App Services app, and it will be needed as a reference while working with many MongoDB products. 

Note: The client app refers to your actual web app whilst the App Services app refers to the app we create on the cloud, which resides on the Atlas App Services server. 

You can easily copy your App ID from the App Services UI.

.
* Sync `config`: Within the `sync` block, we supply the information shown below. 

`user`: Passing in the user’s login credentials
`flexible`: Defining what Sync mode the app will use 
`initialSubscriptions`: Defining the queries for the data that needs to be synced; the two parameters `subs` and `realm` refer to the sync’s subscriptions and local database instance. 

We now have built a crucial part that manages the data model used for Sync, authentication, sync mode, and subscription. This part customizes the initial data sync process and tailors it to fit the business logic. 

(5)
Our coffee app calculates the cups of coffee we consume during the day. The simple app relies on inputs from the user. In this case, the data flowing in and out of the app is the number of different coffees the user consumes.

, as shown by the code snippet below. 

```
    await coffeeCollection.updateOne( 
   { user_id: user.id },
   { $set: { consumed: total } },
   { upsert: true }
 );
```

Here, we use `upsert` to update and insert the changed values of specific coffee drinks. As you can see, this code snippet works directly with documents stored in the back end. Instead of opening up a realm with the Device Sync feature, the coffee app without Device Sync still uses Web SDK. 

However, the above-described method is also known as “MongoDB Atlas Client.” The name itself is quite self-explanatory as it allows the client application to take advantage of Atlas features and access data from your app directly.

2: Which one should we choose?

Essentially, whether you should use the Device Sync feature from the Web SDK or follow the more traditional Atlas Client depends on your use cases, working environments, and existing codebase. We talked about two different ways to keep data updated between the client apps and the back end. Although both sample apps don’t look very different due to their simple functionality, this will be quite different in more complicated applications. 
 
Look at the UI of both implementations of the web apps: 

, functions) we can keep a heavy workload on the App Services server while making sure our web app remains responsive.

* No encryption at rest: You can understand this limitation as Realm JS Web SDK only encrypts data in transit between the browser and server over HTTPS. Anything that’s saved in the device’s memory will be stored in a non-encrypted format. 

However, there’s no need to panic. As previously mentioned, Device Sync uses roles and rules to strictly control users’ access permissions to different data. 

A limitation of Atlas Client is the way data is updated/downloaded between the client and server. Compared to Device Sync, Atlas Client does not have the ability to keep data synced automatically. This can also be seen as a feature, in some use cases, where data should only be synced manually.

## Conclusion

In this article, we: 

* Talked about the usage of the App Services Web SDK in a React web app. 
* Compared Web SDK’s Device Sync feature against Atlas Client.
* Discussed which method we should choose.

The completed code examples are available in the appendix below. You can use them as live examples of MongoDB’s App Services Web SDK. As previously mentioned, the coffee apps are designed to be simple and straightforward when it comes to demoing the basic functionality of the Web SDK and its sync feature. It is also easy to add extra features and tailor the app’s source code according to your specific needs. For example:

 1. Instead of anonymous authentication, further configure `credentials` to use other more secure auth methods, such as email/password.
 2. Modify the data model to fit your app’s theme. For now, our coffee app keeps track of coffee consumption. However, the app can be quickly rebuilt into a recipe app or something similar without complicated modifications and refactoring. 

Alternatively, the example apps can also serve as starting points for your own web app project. 

App Services’ Web SDK is MongoDB’s answer to developing modern web apps that take advantage of Realm (a local database) and Atlas (a cloud storage solution). Web SDK now supports Device Sync (in preview) whilst before the preview release, Atlas Client allowed web apps to modify and manipulate data on the server. Both of the solutions have the use cases where they are the best fit, and there is no “right answer” that you need to follow. 

As a developer, a better choice can be made by first figuring out the purpose of the app and how you would like it to interact with users. If you already have been working on an existing project, it is beneficial to check whether you indeed need the background auto-syncing feature (Device Sync), compared to using queries to perform CRUD operations (Atlas Client). Take a look at our example app and notice the `App.js` file contains the basic components that are needed for Device Sync to work. Therefore, you will be able to decide whether it is a good idea to integrate Device Sync into your project.

### Appendix (Useful links)

* App Services
* Atlas Device SDK for the web
* Realm Web and Atlas Device Sync (preview)
* Realm SDK references
* The coffee apps source code: 
   - Coffee app with Device Sync
   - Coffee app without Device Sync

  [1]: https://images.contentstack.io/v3/assets/blt39790b633ee0d5a7/blt6af95a5a3f41ac6d/664500a901b7992a8fd19134/device-sync-between-client-device-atlas.png
  [2]: https://images.contentstack.io/v3/assets/blt39790b633ee0d5a7/bltaca56a39c1fbdbd2/6645015652b746f9042818d7/create-project.png
  [3]: https://images.contentstack.io/v3/assets/blt39790b633ee0d5a7/bltcc5cf094e67020f1/66450181acadaf4f23726805/deploy-database.png
  [4]: https://images.contentstack.io/v3/assets/blt39790b633ee0d5a7/bltebeb83b68b03a525/664501d366b81d2b3033f241/database-deployments.png
  [5]: https://images.contentstack.io/v3/assets/blt39790b633ee0d5a7/bltcc5e7b6718067804/6645021499f5a835bfc369c4/create-app.png
  [6]: https://images.contentstack.io/v3/assets/blt39790b633ee0d5a7/bltbe5631204b1c717c/664502448c5cd134d503a6e6/app-id-code.png
  [7]: https://images.contentstack.io/v3/assets/blt39790b633ee0d5a7/blt8b6e7bbe222c51bc/66450296a3f9dfd191c0eeb5/define-schema.png
  [8]: https://images.contentstack.io/v3/assets/blt39790b633ee0d5a7/blt763b14b569b2b372/664502be5c24836146bc18f2/configure-schema.png
  [9]: https://images.contentstack.io/v3/assets/blt39790b633ee0d5a7/blt3c56ca7b13ca10fd/6645033fefc97a60764befe9/device-sync-roadmap.png
  [10]: https://images.contentstack.io/v3/assets/blt39790b633ee0d5a7/blt56fd820a250bd117/664503915c2483382cbc1901/configure-access.png
  [11]: https://images.contentstack.io/v3/assets/blt39790b633ee0d5a7/blte63e871b8c2ece1d/664503b699f5a89764c369dc/server-side-schema.png
  [12]: https://images.contentstack.io/v3/assets/blt39790b633ee0d5a7/blt6cf1ae1ff25656f0/6645057a4df3f52f6aee7df4/development-mode-switch.png
  [13]: https://images.contentstack.io/v3/assets/blt39790b633ee0d5a7/blt25990d0bdcb9dccd/6645059da0104b10b7c6459d/auto-generated-data-model.png
  [14]: https://images.contentstack.io/v3/assets/blt39790b633ee0d5a7/bltf415f5c37901fc1d/6645154ba0104bde23c6465c/side-panel.png
  [15]: https://images.contentstack.io/v3/assets/blt39790b633ee0d5a7/blt478c0ad63be16e4b/664515915c24835ebebc19b0/auto-generated-data-model.png
  [16]: https://images.contentstack.io/v3/assets/blt39790b633ee0d5a7/blte1c7f47382325f02/664515bb8c5cd1758403a7ac/switching-on-development-mode.png
  [17]: https://images.contentstack.io/v3/assets/blt39790b633ee0d5a7/bltda38b0c77bf82622/664516a466b81d234f33f33e/coffee-drinks-quantity-tracker-UI.png
  [18]: https://images.contentstack.io/v3/assets/blt39790b633ee0d5a7/bltc0a269aa5d954891/66451902a3f9df91c3c0efe0/coffee-drinks-quantity-tracker-UI.png
  [19]: https://images.contentstack.io/v3/assets/blt39790b633ee0d5a7/blt5dc1e20f474f4c6b/6645191abfbef587de5f695f/web-app-features-atlas-client.png