Building a quiz web app using Blazor, Cosmos DB and Azure functions

Are you curious about how to create a dynamic and engaging quiz web app? Learn how to combine the power of Blazor, Cosmos DB, and Azure Functions to build a fully functional quiz web app that will impress your users and make them return for more. Get ready to dive into the serverless architecture and learn how to create a seamless user experience with the latest web development tools.

Author: Simona Balan

Nowadays, technology is advancing at an exponential rate, and it's increasingly important to keep up with these changes. As it progresses, it brings new opportunities, challenges, and possibilities for growth and innovation. With the right mindset and willingness to learn, anyone can stay ahead of the curve and take advantage of new opportunities. Thus, in this article, we plan to present you with a fun little quiz app that allows an admin to manage a list of questions and a user to take the quiz and see the real-time results.

For faster development and for smaller scoped projects, the serverless development model has proved to be a good choice because :

  • It can be more cost-effective than traditional server-based computing since you only pay for the resources you use.
  • It scales automatically, depending on the demands of the workload. This makes it easier to handle sudden spikes in traffic or user requests.
  • It allows the developers to quickly deploy code without having to worry about server configuration or maintenance.
  • It provides high availability, with built-in redundancy and failover capabilities. This means that your application is less likely to experience downtime or service disruptions.

In order to achieve this, we will be using Azure functions, Azure Cosmos DB, and for a boost in productivity also, Blazor for creating the client application.

AGENDA

  • ABOUT AZURE FUNCTIONS
  • ABOUT COSMOSDB
  • ABOUT BLAZOR
  • SETUP THE AZURE COSMOS DB ACCOUNT
  • CREATE THE AZURE FUNCTION PROJECT IN VISUAL STUDIO
  • PUBLISH THE AZURE FUNCTION PROJECT
  • CREATE THE BLAZOR CLIENT PROJECT

ABOUT AZURE FUNCTIONS

Azure Functions is a serverless computing service from Microsoft Azure that enables you to run event-driven serverless applications on a pay-per-execution basis. With Azure Functions, you can run your code in response to events and triggers, and you only pay for the time your code runs.

It is widely used across the industry because it has many advantages:

  • Scalability: They automatically scale out to meet demand and only run when triggered, which means you don't have to worry about provisioning or managing servers.
  • Cost-effective: You only pay for the time your code is running, which can be much cheaper than running a dedicated server or VM.
  • Flexibility: They support multiple programming languages and integrate with other Azure services.
  • Fast development: They provide many templates and connectors that can help you quickly create and deploy functions, allowing you to develop and deploy faster.

ABOUT COSMOSDB

Azure Cosmos DB is a fully managed, globally distributed, multi-model database service designed for modern web and mobile applications. It supports document, key-value, graph, and column-family data models, providing unmatched developer productivity and performance.

It is a strong option because it is:

  • Globally distributed: It provides seamless replication across different regions, allowing applications to read and write data from anywhere in the world with very low latency.
  • Scalability: It scales vertically and horizontally, meaning it can handle a massive amount of data, and the throughput can be easily scaled up or down to meet application demands.
  • Multi-model support: It supports multiple data models, making it ideal for building modern web and mobile applications that require a variety of data models.
  • Consistency: It guarantees strong consistency, which means that clients can always read the latest version of data.
  • Security: It provides several security features, including encryption at rest and in transit, role-based access control, and automatic patching.

Things to consider about it:

  • Complexity: Cosmos DB is a complex system, and it can be challenging to set up and manage.
  • Cost: Cosmos DB can be more expensive than other databases, especially for small-scale applications.

Since we are planning to use Azure functions, there is a handy extension that can help us to make the setup easier.

It is called Microsoft.Azure.WebJobs.Extensions.CosmosDB, which we can use to have an Azure DocumentDB binding to easily create, read, and update JSON documents from a WebJob.

ABOUT BLAZOR

Blazor is a web framework developed by Microsoft that allows developers to build web applications using C# and .NET.

With Blazor, developers can create web applications using the same programming language and tooling they use to create desktop and mobile applications, which can make development more efficient and easier to manage.

It contains some important features that should take into account like:

  • Building Web UIs with C# instead of JavaScript or TypeScript offers the possibility to implement in C# on both the client side and the server side.
  • Create and use reusable components written in C#
  • Data binding with the HTML DOM (limited two-way binding): @bind:get, @bind:set
  • Ahead-of-time (AOT) compilation, where you can compile your .NET code directly into Web Assembly. AOT compilation results in runtime performance improvements at the expense of a larger app
  • Works in all modern web browsers, including mobile browsers
  • Supports HTML and CSS - although Blazor uses Razor views, the result is rendered in HTML and CSS. Therefore, one could use any CSS feature or library for stylization and any HTML attribute.
  • Virtualization is a technique that limits UI rendering to display only the parts currently visible to the end user without rendering all the items at once.
  • Blazor WASM supports lazy loading, which improves the start-up speed of your app. Essentially, this feature defers loading a resource until it's requested by the user.

Presentations being done, we can get to work.

SETUP THE AZURE COSMOS DB ACCOUNT

Step 1. Login into the Azure Portal where you have the subscription.

Step 2. Choose “Create new Resource…”, select “Azure CosmosDB for NoSql”, this will open a new page with certain properties to be filled in, notice the image on the right =>

Subscription – the user's Azure subscription under which he attempts to create the Resource

ResourceGroup – the resource group under it creates the site. You can keep it as it is or you can create one new, by clicking on “Create new Resource…”

AccountName – mention your CosmosDB account name

Location – West Europe

CapacityMode – Serverless (suitable for unpredictable and intermittent workloads)

Step 3. Leave the other sections with default values. At the end, you will have the following specifications for your database:

Click on the “Create” button. After resource will be created, click on “Go to Resource”

Step 4. After clicking on “Go to Resource”, select “Data Explorer” from the left panel. Then, click on “New Container”.

Step 5. An “Add Container” pane will appear. You need to fill in the details to create a new container for your Azure Cosmos DB. Refer to the image shown left.

You can fill in the details indicated below.

Database ID: You can give any name to your database. Here I am using QUIZDB.

Container ID: Enter the name of your container. Here I am using QuizContainer.

Partition key: The Partition key is used to automatically partition data among multiple servers for scalability. Put the value as “/id”.

Click on the “OK” button to create the database.

Step 6. You can click on Items, go on “New Item” and write (in the json structure), then click Save => Download Code_New Item

Mention: The Keys section contains the ConnectionString which we'll use later in the config settings of the AzureFunction app.

In the following sections we will create the quiz application in Visual Studio with following structure:

  • BlazorQuiz.Common - The core domain models that we are going to use to define our business.
  • BlazorQuizFuctionApp - The Azure functions required to manage a quiz.
  • BlazorQuizUIApp - The Blazor UI project containing the client application.

CREATE THE AZURE FUNCTION PROJECT IN VISUAL STUDIO

Step 1. Open Visual Studio, and select “New Project” -> write “Azure Function”, the option will appear

Step 2. On the next screen, name your project: BlazorQuizFunctionApp, set the location, solution name and set Next

Step 3. Another additional screen appears, in which you can select the framework that is used behind (.net 6), the function template (HttpTrigger), and the authorization level (Anonymous)

Step 4. Add reference to our CosmosDB helper by right clicking on Dependencies and choosing Manage Nuget Packages. Search for Microsoft.Azure.WebJobs.Extensions.CosmosDB and install.

After setting function project basis, you can safely delete the default function class called Function1.cs, since we won’t need it anymore.

Step 5. For the Model class that we'll use, a new class library project will be created using .Net 6, with only a Models folder and a class inside, named: Quiz.cs. This will be set up in a separate folder as the two projects will share it.

The Quiz.cs class will have the following properties inside => Download Code_Quiz Class

Step 6. Add a reference in the AzureFunction project to the BlazorQuiz.Common project, so we can have access to the model class.

Step 7. Create a new class file called BlazorQuiz.cs and create an Azure function to retrieve all the questions regarding the "Blazor" subject from the QuizContainer inside the blazorquizdb CosmosDb database => Download Code_Blazor Quiz

Make sure you change the database name to the one that you chose when you created the container: QUIZDB and the container name: QUIZContainer. We are using a HttpRequest and the CosmosDB extension to pull all the records from the Quiz container.

The result will be 200 OK containing the List with all the questions which are all part of the same quiz for now.

Step 8. The BlazorQuiz contains a PostQuestion method for adding a new Question to the Quiz container => Download Code_Post question.

To add new data, we use a DocumentClient instead of an HttpRequest. We take the object we want to send and deserialize it so that we can push the raw JSON to the database. Don't forget to update the database name in both places where it appears. Additionally, make sure to update the collectionUri when you create it. This method is specifically designed to add a new question that can be set by an admin for the quiz.

Step 9. The BlazorQuiz contains a DELETE method, that allows for an admin to delete the question => Download Code_Delete Question

Step 10. After that, in the local.settings.json, fill in the connection string setting that you have in Azure for BlazorQuizDB Cosmos database in the Primary Keys section.

Make sure to fill in the DocumentsKey and the DocumentsDbEndpoint also.

Now, we are ready to Publish our FunctionApp.

PUBLISH THE AZURE FUNCTION PROJECT

Step 1. Create an empty resource AzureFunction in portal Azure, by clicking on “Create Function App” in Azure Portal (with below specifications).

Name – the resource name that will be used further when being accessed globally

SubscriptionName – the azure subscription under which you create the Function resource in Azure

ResourceGroup – select an existing or Create New

PlanType – Consumption (Serverless), it will make you only pay for the executions of your function app

Click on Review+Create.

Step 2. In VisualStudio, right-click on the BlazorQuizFunctionApp project , click on “Publish…” menu. Select the Publish target as Azure.

Step 3. Select Azure Function App (Windows)

Step 4. In the next window, all the existing Azure Functions will be listed (from Azure portal), with the possibility also to create one new. We will choose the one which we just created before:

Step 5. Click on Next, it will be shown the last step “Deployment type” and leave selected the default option (with “pubxml” publish file).

Then click on Finish. Now you are on the Publish page again.

Step 6. In the Hosting section, you have a “…” button, if you click on it, you will see “Manage Azure AppService” settings.

Step 7. You will see an “Application Settings” popup.

In the DBConnectionString section, we will want to use for the Remote option the same value as it is in Local, that would mean when the app is deployed in Azure, the Remote value will be used. Click on the “Insert value from Local” and the value will be copied from Local to Remote. Click then on OK. Do the same for DocumentsDbEndpoint and DocumentsKey app settings.

Step 8. Ok, now we are done with all the configurations. You can click on the Publish button in Azure and the app is being deployed. After the deploy is done, you can click on the Function App Url, that has the form with function domain + “/api/BlazorQuiz” in the browser and should be displayed the list with all the questions.

Step 9. Enable CORS for the Azure FunctionApp. We will need to enable CORS for the Blazor application to be allowed to make calls to the Azure Function App, and in order to avoid cross-origin errors. To do this, go to CORS section in Azure, and in the “Allowed Origins” section, make an entry with “*”, like in the left side image:

CREATE THE BLAZOR CLIENT PROJECT

Step 1. Right-click on the solution BlazorQuizUIApp.sln and click on “Add New Project…” menu.

Step 2. From the project types of the popup, select Blazor WebAssembly project, then write for its name: “BlazorQuizUIApp”. In the Additional Information window, set the details as shown in the right side image =>

Then click on Create.

Step 3. Create a new Razor component called EditBlazorQuiz.razor by right-click on Pages folder, then Create New Razor Component, and set the following code in it => Download Code_Blazor Quiz

  • This component is for getting all the questions, add and delete a question for the Blazor quiz.
  • The requests are done using the published function url: https://blazorquizfunctionapp20221013002852.azurewebsites.net/
  • In the OnInitializedAsync method, we are getting all the questions list.
  • The Quiz model class is taken from the BlazorQuizUIApp.Common project.
  • In the NavMenu.razor component, delete the FetchData and Counter links and instead add EditQuiz menu link to the div element => Download Code_Edit Quiz.

Step 4. Create a new Razor component called TakeBlazorQuiz.razor by right-click on Pages folder, then Create New Razor Component, and set the following code in it => Download Code_Create New Razor Component.

  • This component loads the quiz in the OnInitializedAsync method by making an http call.
  • It also contains an UpdateScore function that for a chosen answer and a quiz updates the score if the answer is correct.
  • For each quiz question we are rendering a radio input form with the possible answers for that questions and attach the UpdateScore function on the onchange event.
  • If the answer is correct the score is increase if not it remains the same.

Bibliography:

https://www.okta.com/identity-101/serverless-computing/

https://www.syncfusion.com/blogs/post/7-features-of-blazor-that-make-it-an-outstanding-framework-for-web-development.aspx

https://www.claudiobernasconi.ch/2022/01/20/how-to-create-an-azure-function-app-using-csharp-net-6/

https://learn.microsoft.com/en-us/events/azure-serverless-azure-serverless-conf/serverless-apps-with-blazor-webassembly-and-azure-static-web-apps

Microsoft Azure. "Serverless computing". https://azure.microsoft.com/en-us/overview/serverless-computing/

Microsoft Azure. "Azure Functions". https://azure.microsoft.com/en-us/services/functions/

Official Microsoft Blazor documentation: https://docs.microsoft.com/en-us/aspnet/core/blazor/?view=aspnetcore-6.0

Blazor University: https://blazor-university.com/