Implementing a Visitor Counter on Azure Resume Challenge

oluwatobi2001 - Sep 2 - - Dev Community

Azure cloud resume challenge provides a thrilling journey for cloud enthusiasts and helps give you portfolio-worthy projects. You can get more details on how to get started here.
One of the major steps in completing the challenge involved completing and implementing a visitor counter that records the number of visitors to the website. This article details how I went about implementing this, the obstacles I faced and how I was able to circumvent them.
To follow along with this tutorial, here are some prerequisites.

  • Possession of an Azure account with an active subscription
  • Knowledge of Azure storage. (here is an article that discusses it in detail )
  • Familiarity with Azure Functions and Azure Cosmos DB.
  • JavaScript knowledge

With that, let's get started.

Brief intro

So far, I have completed the preceding steps in the Azure cloud challenge which is creating and deploying the Static resume on the Azure platform. I wrote a detailed article covering how I implemented it here.

Moving on to the next stage of the challenge which involved me implementing the visitor count API for my site, I decided to set it up using Azure Cosmos DB as the database of choice and Azure functions to execute concise serverless functions using JavaScript. My choice for a serverless stems from the increased efficiency and cost-effectiveness it provides. I also configured my front-end resume site to include the relevant JavaScript which consumes the API and implements a responsive frontend. I would highlight on the tools used in the next paragraph.

Azure Cosmos DB

Azure Cosmos Db is a cloud database made available by Azure. It's similar to the popular Dynamo DB used in AWS and Big Query in GCP. Azure Cosmos DB offers a wide variety of database options ranging from relational databases such as SQL to NoSQL database services. This provides us with the ability to store and update data directly to the cloud seamlessly and affordably.

Azure Functions

This is a serverless implementation of backend applications on the Azure platform. it's easily compatible with a lot of programming languages such as Node JS, .Net, Python, C# and others. These functions can also be configured to be invoked by several triggers such as HTTP requests, database updates etc.
Moving on, will be highlighting the process of setting up the visitor count API and then, integrate it to our frontend.

Setting up Azure Cosmos DB

On the Azure Portal home page, click on the navigation button and select Azure Cosmos DB. It will display an image similar to the one below.

Cosmos DB home page

Thereafter, click on the create button on the top of the page. In order to implement the project, we would be sticking with the Azure Cosmos DB for NoSQl. Also ensure to include the resource group for the Database. Its more preferred to have a single resource group managing all the applications involved in this project.

Image description

Image description
on successful creation of the database , navigate to the data explorer tab which allows us to easily configure the database properties.

While in the data explorer app, click on new container. This allows us to create a database id and a container id to store our data.

Image description
Image description

You would also be required to enter a partition key. This can be renamed based on your preference.

Image description
Thereafter, you would need to customize the items field to include the visitors count field.

{
"id": "item",
"count" : 0
}
Enter fullscreen mode Exit fullscreen mode

Setting up Azure functions

To go on with the tutorial, we will now create the Azure function for this tutorial. Creating the function will require us to access the Azure function app directory which serves to manage the various Azure function apps. To successfully create the function application, navigate to Azure function apps and click on Create.

Image description
You would then be offered some plans for application hosting. For the sake of the tutorial, we would be sticking with the consumption plan.
Image description
Thereafter, enter a unique name for the function and select an appropriate Azure resource group. Also, select the runtime stack environment you are quite comfortable with. I intend to utilize Node JS to build the function environment.
Image description

On successful creation of the function app, you should see something similar to this.

Image description
Clicking on the Go to resource button leads us to the function app dashboard. Within the dashboard, kindly click on Create function.

We would then select the http trigger function. This method is adopted in our case, since we intend to communicate with our resume site via browser HTTP requests, we will then be utilizing the httpTrigger1 to serve as our function trigger.
Image description

Image description

In order to configure our server-less Azure function to interact seamlessly with our database, we need to navigate to the defined httpTrigger1 function and click on the integration tab.
Image description

We will click on the add input and add output tabs and then modify it to integrate our database with our function.
Within each tab, enter the database name and the collection name of the database we created. Also, ensure that a new database connection is created in each tab. This will ensure seamless connection with the database.

Image description

Image description

Image description

Upon successful completion, click on the function trigger tab and you will get access to the function dashboard. A default code will be available under the code*test tab.

Now to the main issue I faced in the building the application, I experienced a great deal of difficulty while trying to connect the database to the function due to a flaw in the default function.json code.

The function.json code by default stores the default configuration details needed for easy communicability amongst the function and database.
However, an upgrade from the Azure function version over time has invalidated some fields in the Azure function.json which ultimately led to the errors I experienced.
Here are the 2 fields in question

ConnectionString
collectionName
these two have subsequently been replaced with the connection and containerName strings respectively.

The code below contains the corrected version for the function.json code.

{
  "bindings": [
{
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get",
        "post"
]
},
{
      "type": "http",
      "direction": "out",
      "name": "res"
},
{
      "name": "inputDocument",
      "direction": "in",
      "type": "cosmosDB",
      "methods": [],
      "databaseName": "views_db",
      "containerName": "tutorial-container",
      "connection": "tobi-tuts_DOCUMENTDB"
},
{
      "name": "outputDocument",
      "direction": "out",
      "type": "cosmosDB",
      "methods": [],
      "databaseName": "views_db",
      "containerName": "tutorial-container",
      "connection": "tobi-tuts_DOCUMENTDB"
}
]
}

Enter fullscreen mode Exit fullscreen mode

On successful editing, save the function.json and test the code. If appropriately connected, a response code200 code is displayed.

Now we will go on to configure our Azure serverless function code to be executed.


module.exports = async function (context, req , data) {
    context.log('JavaScript HTTP trigger function processed a request.');

    context.bindings.outputDocument = data[0];
    context.bindings.outputDocument.count += 1;
    context.res = {
        // status: 200, /* Defaults to 200 */
        body: data[0].count
    };
}
Enter fullscreen mode Exit fullscreen mode

Image description
In the code above, the binding database document is accessed and then updated. The total number of visitor counts stored in the database is then fetched and sent as a response message to the frontend. The visitor count is also updated to reflect the new number.

With that, we have completed the backend API of the application. Subsequently, we would be implementing the frontend to successfully seamlessly communicate with the backend API  and update the database.
We will be creating a JS file to manage our fetch requests to the API and also based on the response received, modifies the HTML code to reflect the visitor number.
Here is the code below;

window.addEventListener('DOMContentLoaded', (e) => {
    getVisitorCount();
})
const myApiLink = {Your Azure function link};
const getVisitorCount =() => {
    let count = 0;
fetch(myApiLink , {
    mode: 'cors'
}).then(response => {
    return response.json() }
).then(res => {
const count = res;
document.getElementById('visitorCount').innerHTML = count;
})
return count;
}


Enter fullscreen mode Exit fullscreen mode

The above code is the Frontend JavaScript code in order to retrieve the number of visits and also update the visitor count.

window.addEventListener('DOMContentLoaded', (e) => {
    getVisitorCount();
})
Enter fullscreen mode Exit fullscreen mode

This ensures that the function getVisitorCount gets executed only after the Web page have been loaded. Also, we defined the ApiLink variable which is the URL of the Azure function we built in the preceding section. You can obtain this link on the functions dashboard.

const getVisitorCount =() => {
    let count = 0;
fetch(myApiLink , {
    mode: 'cors'
}).then(response => {
    return response.json() }
).then(res => {
const count = res;
document.getElementById('visitorCount').innerHTML = count;
})
return count;
}
Enter fullscreen mode Exit fullscreen mode

The code above sets the preliminary count to 0. the fetch request is used to access the Azure function and the result obtained is then dynamically updated in the homepage.
With that, we have come to the end of the tutorial. You can check here to see the expected result.

Image description

Additional Info.

So far, we have implemented the Visitor count API on our resume project. You can further raise the challenge by only tracking unique visits to the site. This can be sorted by entering a representation of each visitor's IP to avoid counting each visit by a visitor multiple times. Additionally, you can experiment with the challenge by using other Azure storage accounts such as Azure file storage/object storage in place of Cosmos DB to obtain similar results.

Conclusion

You can also interact with me on my blog and check out my other articles here. Till next time, keep on coding!

. . . . . . . . . . .