Table of Contents
How to create a REST API using MongoDB
The process will be as follows:
- Install MongoDB on your server
- Populate MongoDB with your data
- Create the REST API logic to interact with your data
- Create a REST API using the RapidAPI Provider Dashboard
- Defining the API name, description, and logo
- Specifying API endpoints and available parameters
- Choose API plans and pricing
- Provide more detailed documentation about your API
Step 1. Install MongoDB on your server
To install MongoDB you will need root access to your server. That means you will have either a Dedicated Server or a Virtual Private Server (VPS). If you are using an Elastic Compute Cloud (EC2) server there is an example configuration. In my case, I have a VPS with root access enabled. I followed the MongoDB RedHat install instructions. The first step was creating a file at /etc/yum.repos.d/mongodb-org-4.2.repo
with the following contents:
[mongodb-org-4.2] name=MongoDB Repository baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.2/x86_64/ gpgcheck=1 enabled=1 gpgkey=https://www.mongodb.org/static/pgp/server-4.2.asc
Then I installed the MongoDB packages with yum install -y mongodb-org
. Next I ran it using service mongod start
.
Then when I ran it by typing ‘mongo’ I got a welcome message, several information messages, and a command prompt!
Step 2. Populate MongoDB with your data
The simplest form of an API is one that is read-only. That means data can be retrieved but not added, updated, or removed. For my first API on the RapidAPI platform, I wanted to keep things simple. For the Proverbs API, there are only 2 fields in one collection in one MongoDB database. A MongoDB collection is analogous to a table in a SQL database.
The ‘mongoimport’ command is part of the mongo package and it allows you to import data files. There are three types of data files you can import from the command line. They are JavaScript Object Notation (JSON), comma separated values (CSV), and tab separated values (TSV). I created .tsv files because there are commas in many of the quotes. An example of the command I used was as follows:
mongoimport -d proverbsdb -c proverbs --type tsv --file "rumi quotes.tsv" --fields=proverb,source
In this command, ‘proverbsdb’ is the name of the database and ‘proverbs’ is the name of the collection. The data file name is ‘rumi quotes.tsv’ and the two fields in the file (used in the collection) are specified in the ‘fields’ tag.
Step 3. Create the MongoDB REST API logic to interact with your data
First, we validate the input parameters sent in the URL.
/* File: proverbs-api.php Description: This api takes 3 optional inputs, queries a local MongoDB collection using the inputs as filters if needed, then returns a proverb and source in JSON. Inputs: includeSources - comma separated list of sources to include excludeSources - comma separated list of sources to exclude searchTerm - term used to filter results (only letters, numbers, and spaces allowed) Outputs: JSON object with the following fields: source - source of the proverb proverb - text of the proverb */ global $debug; $debug=false; $apiKeyAllowed = "xxxxxxxxxxxxxxxxxxxxxxxxxxxx"; $sourcesAllowed = ['proverbs','shakespeare','emerson','thoreau','rumi','tao te ching']; //Collect Inputs $includeSrcs = (!empty($_GET['includeSources']))?explode(",",$_GET['includeSources']):[]; $excludeSrcs = (!empty($_GET['excludeSources']))?explode(",",$_GET['excludeSources']):[]; //Only keep letters, numbers, and spaces in the search term $searchTerm = (!empty($_GET['searchTerm']))?preg_replace('/[^a-zA-Z0-9 ]/','',$_GET['searchTerm']):''; //Validate source filters $includeSrcFilters=$excludeSrcFilters=array(); foreach($includeSrcs as $includeSrc) { if (in_array(strtolower($includeSrc),$sourcesAllowed)) { $includeSrcFilters[] = strtolower($includeSrc); } } if (empty($includeSrcFilters)) { foreach($excludeSrcs as $excludeSrc) { if (in_array(strtolower($excludeSrc),$sourcesAllowed)) { $excludeSrcFilters[] = strtolower($excludeSrc); } } }
Next, we use the inputs to construct a MongoDB query, execute the query, and echo the result in JSON format:
//Make sure this is a valid request, otherwise stop $headers = apache_request_headers(); if (empty($headers['X-Rapidapi-Proxy-Secret'])) { die(); } else if ($headers['X-Rapidapi-Proxy-Secret']!==$apiKeyAllowed) { die(); } else { //Now we can pull a proverb from the local database //Decide if we are including or excluding sources $ORClause = $ANDClause = $OuterANDClause = $OuterANDEND = ''; //Create a filter for sources to include or exclude if (!empty($includeSrcFilters)) { $ORClause = '{$or: ['; foreach ($includeSrcFilters as $includeSource) { $ORClause.='{source : { $regex : /'.$includeSource.'/, $options: '-i' }},'; } //Trim last comma and close brackets $ORClause = substr($ORClause,0,-1).']}'; } else if (!empty($excludeSrcFilters)) { $ANDClause = '{$and: ['; foreach ($excludeSrcFilters as $excludeSource) { //The brackets in this regular expression define a group of characters. // These need to be found in the source field. The ^ in front is a negation. // This means we are excluding records with a source that matches $excludeSrc. // The i option means it is a case insensitive match $ANDClause.='{source : { $regex : /[^'.$excludeSrc.']/, $options: '-i' }},'; } //trim last comma and close brackets $ANDClause = substr($ANDClause,0,-1).']}'; } //Now construct the search term clause - this will wrap around any source clause if (!empty($searchTerm)) { $OuterANDClause = '{$and: [{proverb : { $regex : /'.$searchTerm.'/, $options: '-i' }},'; $OuterANDEND = ']}'; } // Do not include the _id field in the results and return 1 random sample of all matching documents $sampleAggregate = '{ $project: { _id:0 } },{ $sample: { size: 1 } }'; //Single quotes around the parts of the MongoDB command allow us to only escape the operators once. // If we used double quotes we would need $sample instead (like the $match MongoDB operator below) //Construct the command to be executed on the server $mongoCmd = "mongo proverbsdb --quiet --eval "printjson(db.proverbs.aggregate([{$match: $OuterANDClause $ORClause $ANDClause $OuterANDEND}, $sampleAggregate]).toArray())""; //This line can be used to make sure we are sending a valid command to Mongo if ($debug) echo "n mongoCmd is $mongoCmdn"; //Backtick notation executes the command as if it was typed in a console $proverbsJSON = `$mongoCmd`; echo $proverbsJSON; }
Step 4. Create a REST API using the RapidAPI Provider Dashboard
Once we have the data in place, we use the Provider Dashboard to create the API within RapidAPI.
Defining the API name, description, and logo
The first questions we need to answer about the new API are the name, description, and category. I chose Education as the category which matches the other 2 similar APIs. There is also a question about how to specify the API, in my case I’ll leave the default UI option selected. I don’t have a logo so I took a picture of one of the quotes with square dimensions. One thing I noticed is at some points in the flow of creating an API it is not clear what to do next. If in doubt, click on each of the links near the top of the dashboard to make sure you’ve filled them out:
When you get to the Endpoints page, don’t bother entering anything in the form field. Click the button to the right which says “Create REST Endpoint”.
Specifying API endpoints and available parameters
On the Edit Endpoint page, you actually specify the path to a specific endpoint. Also, list what parameters are available. My Proverbs API has one endpoint but it has 3 optional parameters:
On the Edit Endpoint page, you can test your endpoint. This is very important during development. I used that to find errors in my JavaScript code sent to MongoDB to retrieve proverbs. The response is written into a text box so breaks are still in HTML instead of being new lines. For example, the test interface looks like this:
While the users testing your endpoint see the JSON response rendered like this:
Choose API plans and pricing
Once you have your API endpoints defined, it’s time to decide how to monetize your API. The pricing page is intuitive. But if you want to enforce both a daily and monthly limit for a plan you need to create a new object. When you create an object you specify associated endpoints and give it a label.
Provide more detailed documentation about your API
After specifying pricing plans for your API, make sure you specify additional information in the “Docs” tab. This will appear in the about section of your API as follows:
Leave a Reply