# Create a Custom Data Enabled API in MongoDB Atlas in 10 Minutes or Less

## Objectives

-   Deploy a Free Tier Cluster
-   Load Sample Data into your MongoDB Atlas Cluster
-   Create a MongoDB Realm application
-   Create a 3rd Party Service, an API with an HTTP service listener
-   Test the API using Postman

## Prerequisites

-   MongoDB Atlas Account with a Cluster Running
-   Postman Installed - See 

## Getting Started

Creating an Application Programming Interface (API) that exposes data and responds to HTTP requests is very straightforward. With MongoDB Realm, you can create a data enabled endpoint in about 10 minutes or less. In this article, I'll explain the steps to follow to quickly create an API that exposes data from a sample database in MongoDB Atlas. We'll deploy the sample dataset, create a Realm App with an HTTP listener, and then we'll test it using Postman.

> I know that some folks prefer to watch and learn, so I've created this video overview. Be sure to pause the video at the various points where you need to install the required components and complete some of the required steps.
>
> :youtube]{vid=bM3fcw4M-yk}

## Step 1: Deploy a Free Tier Cluster

If you haven't done so already, visit [this link and follow along to deploy a free tier cluster. This cluster will be where we store and manage the data associated with our data API.

## Step 2: Load Sample Datasets into Your Atlas Cluster

MongoDB Atlas offers several sample datasets that you can easily deploy once you launch a cluster. Load the sample datasets by clicking on the three dots button to see additional options, and then select "Load Sample Dataset." This process will take approximately five minutes and will add a number of really helpful databases and collections to your cluster. Be aware that these will consume approximately 350mb of storage. If you intend to use your free tier cluster for an application, you may want to remove some of the datasets that you no longer need. You can always re-deploy these should you need them.

Navigate to the **Collections** tab to see them all. All of the datasets will be created as separate databases prefixed with `sample_` and then the name of the dataset. The one we care about for our API is called `sample_analytics`. Open this database up and you'll see one collection called `customers`. Click on it to see the data we will be working with.

This collection will have 500 documents, with each containing sample Analytics Customer documents. Don't worry about all the fields or the structure of these documents just now—we'll just be using this as a simple data source.

## Step 3: Create a New App

To begin creating a new Application Service, navigation from Atlas to App Services.

At the heart of the entire process are Application Services. There are several from which to choose and to create a data enabled endpoint, you'll choose the HTTP Service with HTTPS Endpoints. HTTPS Endpoints, like they sound, are simply hooks into the web interface of the back end. Coming up, I'll show you the code (a function) that gets executed when the hook receives data from your web client.

To access and create 3rd Party Services, click the link in the left-hand navigation labeled "3rd Party Services."

Next, let's add a service. Find, and click the button labeled "Add a Service."

Next, we'll specify that we're creating an HTTP service and we'll provide a name for the service. The name is not incredibly significant. I'm using `api` in this example.

When you create an HTTP Service, you're enabling access to this service from Realm's serverless functions in the form of an object called `context.services`. More on that later when we create a serverless function attached to this service. Name and add the service and you'll then get to create an Incoming HTTPS Endpoint. This is the process that will be contacted when your clients request data of your API.

Call the HTTPS Endpoint whatever you like, and set the parameters as you see below:

   

 ##### HTTPS Endpoint Properties 
| Property                     | Description                                                                                                                                                                                     |
|------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Name                         | Choose a name for your HTTPS Endpoint... any value will do.                                                                                                                                            |
| Authentication               | This is how your HTTPS Endpoint will authenticate users of your API. For this simple exercise, let's choose `System`.                                                                                  |
| Log Function Arguments       | Enabling this allows you to get additional log content with the arguments sent from your web clients. Turn this on.                                                                             |
| HTTPS Endpoint URL                  | This is the URL created by Realm. Take note of this - we'll be using this URL to test our API.                                                                                                  |
| HTTP Method                  | Our API can listen for the various HTTP methods (GET, POST, PATCH, etc.). Set this to POST for our example.                                                                                     |
| Respond with Result          | Our API can respond to web client requests with a dataset result. You'll want this on for our example.                                                                                          |
| AUTHORIZATION - Can evaluate | This is a JSON expression that must evaluate to TRUE before the function may run. If this field is blank, it will evaluate to TRUE. This expression is evaluated before service-specific rules. |
| Request Validation           | Realm can validate incoming requests to protect against DDOS attacks and users that you don't want accessing your API. Set this to `Require Secret` for our example.                            |
| Secret                       | This is the secret passphrase we'll create and use from our web client. We'll send this using a `PARAM` in the POST request. More on this below.                                                |

As mentioned above, our example API will respond to `POST` requests. Next up, you'll get to create the logic in a function that will be executed whenever your API is contacted with a POST request.

### Defining the Function

Let's define the function that will be executed when the HTTPS Endpoint receives a POST request.

> As you modify the function, and save settings, you will notice a blue bar appear at the top of the console.
>
> 
>
> This appears to let you know you have modified your Realm Application but have not yet deployed those changes. It's good practice to batch your changes. However, make sure you remember to review and deploy prior to testing.

Realm gives you the ability to specify what logic gets executed as a result of receiving a request on the HTTPS Endpoint URL. What you see above is the default function that's created for you when you create the service. It's meant to be an example and show you some of the things you can do in a Realm Backend function. Pay close attention to the `payload` variable. This is what's sent to you by the calling process. In our case, that's going to be from a form, or from an external JavaScript script. We'll come back to this function shortly and modify it accordingly.

Using our sample database `sample_analytics` and our `customers`, let's write a basic function to return 10 customer documents.

And here's the source:

``` JavaScript
exports = function(payload) {
   const mongodb = context.services.get("mongodb-atlas");
   const mycollection = mongodb.db("sample_analytics").collection("customers");
   return mycollection.find({}).limit(10).toArray();
};
```

This is JavaScript - ECMAScript 6, to be specific, also known as ES6 and ECMAScript 2015, was the second major revision to JavaScript.

Let's call out an important element of this script: `context`.

Realm functions can interact with connected services, user information, predefined values, and other functions through modules attached to the global `context` variable.

The `context` variable contains the following modules:

| Property            | Description                                                                  |
|---------------------|------------------------------------------------------------------------------|
| `context.services`  | Access service clients for the services you've configured.                   |
| `context.values`    | Access values that you've defined.                                           |
| `context.user`      | Access information about the user that initiated the request.                |
| `context.request`   | Access information about the HTTP request that triggered this function call. |
| `context.functions` | Execute other functions in your Realm app.                                   |
| `context.http`      | Access the HTTP service for get, post, put, patch, delete, and head actions. |
Once you've set your configuration for the Realm HTTPS Endpoint, copy the HTTPS Endpoint URL, and take note of the Secret you created. You'll need these to begin sending data and testing.

Speaking of testing... Postman is a great tool that enables you to test an API like the one we've just created. Postman acts like a web client - either a web application or a browser.

> If you don't have Postman installed, visit this link (it's free!): 

Let's test our API with Postman:

1.  Launch Postman and click the plus (+ New) to add a new request. You may also use the Launch screen - whichever you're more comfortable with.
2.  Give your request a name and description, and choose/create a collection to save it in.
3.  Paste the HTTPS Endpoint URL you created above into the URL bar in Postman labeled `Enter request URL`.
4.  Change the `METHOD` from `GET` to `POST` - this will match the `HTTP Method` we configured in our HTTPS Endpoint above.
5.  We need to append our `secret` parameter to our request so that our HTTPS Endpoint validates and authorizes the request. Remember, we set the secret parameter above. There are two ways you can send the secret parameter. The first is by appending it to the HTTPS Endpoint URL by adding `?secret=YOURSECRET`. The other is by creating a `Parameter` in Postman. Either way will work.

Once you've added the secret, you can click `SEND` to send the request to your newly created HTTPS Endpoint.

If all goes well, Postman will send a POST request to your API and Realm will execute the Function you created, returning 10 records from the `Sample_Analytics` database, and the `Customers` collection...

``` javascript

{
   "_id": {
         "$oid": "5ca4bbcea2dd94ee58162a68"
   },
   "username": "fmiller",
   "name": "Elizabeth Ray",
   "address": "9286 Bethany Glens\nVasqueztown, CO 22939",
   "birthdate": {
         "$date": {
            "$numberLong": "226117231000"
         }
   },
   "email": "arroyocolton@gmail.com",
   "active": true,
   "accounts": [
         {
            "$numberInt": "371138"
         },
         ...
   ],
   "tier_and_details": {
         "0df078f33aa74a2e9696e0520c1a828a": {
            "tier": "Bronze",
            "id": "0df078f33aa74a2e9696e0520c1a828a",
            "active": true,
            "benefits": [
               "sports tickets"
            ]
         },
         "699456451cc24f028d2aa99d7534c219": {
            "tier": "Bronze",
            "benefits": [
               "24 hour dedicated line",
               "concierge services"
            ],
            "active": true,
            "id": "699456451cc24f028d2aa99d7534c219"
         }
   }
},
// remaining documents clipped for brevity
...
]
```

## Taking This Further

In just a few minutes, we've managed to create an API that exposes (READs) data stored in a MongoDB Database. This is just the beginning, however. From here, you can now expand on the API and create additional methods that handle all aspects of data management, including inserts, updates, and deletes.

To do this, you'll create additional HTTPS Endpoints, or modify this HTTPS Endpoint to take arguments that will control the flow and behavior of your API.

Consider the following example, showing how you might evaluate parameters sent by the client to manage data.

``` JavaScript
exports = async function(payload) {

   const mongodb = context.services.get("mongodb-atlas");
   const db = mongodb.db("sample_analytics");
   const customers = db.collection("customers");

   const cmd=payload.query.command;
   const doc=payload.query.doc;

   switch(cmd) {
   case "create":
      const result= await customers.insertOne(doc);
      if(result) {
            return { text: `Created customer` };   
      }
      return { text: `Error stashing` };
   case "read":
      const findresult = await customers.find({'username': doc.username}).toArray();
      return { findresult };
   case "delete":
      const delresult = await customers.deleteOne( { username: { $eq: payload.query.username }});
      return { text: `Deleted ${delresult.deletedCount} stashed items` };
   default:
      return { text: "Unrecognized command." };
   }
}
```

## Conclusion

MongoDB Realm enables developers to quickly create fully functional application components without having to implement a lot of boilerplate code typically required for APIs. Note that the above example, while basic, should provide you with a good starting point. for you. Please join me in the [Community Forums if you have questions.

You may also be interested in learning more from an episode of the MongoDB Podcast where we covered Mobile Application Development with Realm.

#### Other Resources
Data API Documentation - docs:https://docs.atlas.mongodb.com/api/data-api/