Build a serverless web app in Azure

Developer (Intermediate)

93 minutes to complete

Contributors

In this tutorial, you deploy a simple web application that presents an HTML-based user interface. A serverless backend enables the application to upload images and automatically get captions describing them.

The following diagram shows the Azure services used by the application:

Create a web app in Azure Blob storage

92 minutes remaining

Azure Blob storage is a low-cost and massively scalable service that can be used to host static files. For this tutorial, you use it to serve static content (for example, HTML, JavaScript, CSS) for the web app that you build.

Create a Storage account

A Storage account is an Azure resource that allows you to store tables, queues, files, blobs (objects), and virtual machine disks.

Log in to the Cloud Shell (Bash), by selecting the Enter focus mode button. This button is at the top right or the bottom of the page, depending on how wide your browser window is. Focus mode docks a Cloud Shell window on the right side of your browser window, so you can easily execute commands that are shown in the tutorial.

In Azure, a Resource Group is a container that holds related Azure resources for ease of management. Create a new resource group named first-serverless-app.

The repository is cloned to /home/<username>/functions-first-serverless-web-application.

The client-side web application is located in the www folder and is built using the Vue.js JavaScript framework. Change into the folder and run npm commands to install the application's dependencies and build the application. The last of these commands might take several minutes to complete.

Open the Storage static websites primary endpoint URL in a web browser to view the application.

Summary

In this module, you created a resource group named first-serverless-app containing a Storage account. A blob container named $web in the Storage account stores the static content for your web application and makes the content available publicly. Next, you learn how to use a serverless function to upload images to Blob storage from this web application.

Upload images to Blob storage with Azure Functions

80 minutes remaining

The application that you're building is a photo gallery. It uses client-side JavaScript to call APIs to upload and display images. In this module, you create an API using a serverless function that generates a time-limited URL to upload an image. The web application uses the generated URL to upload an image to Blob storage using the Blob storage REST API.

Create a blob storage container for images

The application requires a separate storage container to upload and host images.

Ensure you are still signed in to the Cloud Shell (bash). If not, select Enter focus mode to open a Cloud Shell window.

Create a new container named images in your storage account with public access to all blobs.

Create an Azure Function app

Azure Functions is a service for running serverless functions. A serverless function can be triggered (called) by events such as an HTTP request or when a blob is created in a storage container.

An Azure Function app is a container for one or more serverless functions.

Create a new Azure Function app with a unique name in the resource group you created earlier named first-serverless-app. Function apps require a Storage account; in this tutorial, you use the existing storage account.

Configure the function app

The function app in this tutorial requires version 1.x of the Functions runtime. Setting the FUNCTIONS_EXTENSION_VERSION application setting to ~1 pins the function app to the latest 1.x version. Set application settings with the az functionapp config appsettings set command.

In the following Azure CLI command, `<app_name> is the name of your function app.

Create an HTTP-triggered serverless function

The photo gallery web application makes an HTTP request to serverless function to generate a time-limited URL to securely upload an image to Blob storage. The function is triggered by an HTTP request and uses the Azure Storage SDK to generate and return the secure URL.

After the Function app is created, search for it in the Azure Portal using the Search box and click to open it.

In the function app window's left hand navigation, hover over Functions and click + to start creating a new serverless function.

Click Custom function to see a list of function templates.

Find the HttpTrigger template and click the language to use (C# or JavaScript).

Use these values to create a function that generates a blob upload URL.

Setting

Suggested value

Description

Language

C# or JavaScript

Select the language you want to use.

Name your function

GetUploadUrl

Type this name exactly as shown so the application can discover the function.

(JavaScript) This function requires the azure-storage package from npm to generate the shared access signature (SAS) token required to build the secure URL. To install the npm package, click on the Function App's name on the left navigation and click Platform features.

(JavaScript) Click Console to reveal a console window.

(JavaScript) Ensure the current directory is d:\home\site\wwwroot by running the command cd d:\home\site\wwwroot.

(JavaScript) Run the command npm init -y to create an empty package.json file.

(JavaScript) Run the command npm install --save azure-storage in the console to install the package and save it in package.json. It may take a minute or two to complete the operation.

(JavaScript) Click on the function name (GetUploadUrl) in the left navigation to reveal the function, replace all of index.js with the content of javascript/GetUploadUrl/index.js.

Click Logs below the code window to expand the logs panel.

Click Save. Check the logs panel to ensure the function is successfully compiled.

The function generates what is called a shared access signature (SAS) URL that is used to upload a file to Blob storage. The SAS URL is valid for a short period of time and only allows a single file to be uploaded. Consult the Blob storage documentation for more information on using shared access signatures.

Add an environment variable for the storage connection string

The function you just created requires a connection string for the Storage account so that it can generate the SAS URL. Instead of hardcoding the connection string in the function's body, it can be stored as an application setting. Application settings are accessible as environment variables by all functions in the Function app.

In the Cloud Shell, query the Storage account connection string and save it to a bash variable named STORAGE_CONNECTION_STRING.

Confirm that the command's output contains the new application setting with the correct value.

Test the serverless function

In addition to creating and editing functions, the Azure portal also provides an built-in tool for testing functions.

To test the HTTP serverless function, click on the Test tab on the right of the code window to expand the test panel.

Change the Http method to GET.

Under Query, click Add parameter* and add the following parameter:

name

value

filename

image1.jpg

Click Run in the test panel to send an HTTP request to the function.

The function returns an upload URL in the output. The function execution appears in the logs panel.

Configure CORS in the function app

Because the app's frontend is hosted in Blob storage, it has a different domain name than the Azure Function app. For the client-side JavaScript to successfully call the function you just created, the function app needs to be configured for cross-origin resource sharing (CORS).

In the left navigation bar of the function app window, click on the name of your function app.

Click on Platform features to view a list of advanced features.

Under API, click CORS.

Add an allow origin for the application URL from the previous module, omitting the trailing / (for example: https://firstserverlessweb.z4.web.core.windows.net).

Click Save.

C#

(C#) Navigate back to the GetUploadUrl function, and then select the Integrate tab.

(C#) Under Selected HTTP methods, select OPTIONS.

GET, POST, and OPTIONS should all be selected. CORS uses the OPTIONS method, which is not selected by default for C# functions.

(C#) Click Save.

Still in the portal, navigate to the function app, select the Overview tab, and then click Restart to make sure that the changes for CORS take effect.

Configure CORS in the Storage account

Because the app also makes client-side JavaScript calls to Blob Storage to upload files, you also have to configure the Storage account for CORS.

Run the following command to allow all origins to upload files to the Storage account.

Modify the web app to upload images

The web app retrieves settings from a file named settings.js. In the following steps, you create the file using Cloud Shell, then set window.apiBaseUrl to the URL of the Function app and window.blobBaseUrl to the URL of the Azure Blob Storage endpoint.

In the Cloud Shell, ensure that the current directory is the www/dist folder.

cd ~/functions-first-serverless-web-application/www/dist

Query the function app's URL and store it in a bash variable named FUNCTION_APP_URL.

Test the web application

At this point, the gallery application is able to upload an image to Blob storage, but it can't display images yet. It will try to call a GetImages function that doesn't exist yet because you create it in a later module. That call will fail, and the web page will appear to be stuck on "Analyzing...", but the image you select will be successfully uploaded.

You can verify an image is successfully uploaded by checking the contents of the images container in the Azure portal.

In a browser window, browse to the application. Select an image file and upload it. The upload completes, but because we haven't added the ability to display images yet, the app doesn't show the uploaded photo. (The web page appears to be stuck on "Analyzing image..."; you'll fix that later.)

In the Cloud Shell, confirm the image was uploaded to the images container.

Summary

In this module, you created an Azure Function app and learned how to use a serverless function to allow a web application to upload images to Blob storage. Next, you learn how to create thumbnails for the uploaded images using a Blob triggered serverless function.

Resize images with Azure Functions

60 minutes remaining

In the previous module, you saw how a serverless function can facilitate the secure uploading of images to Blob storage from a web application. In this module, you create another serverless function to watch for uploaded images and create thumbnails from them.

Create a blob storage container for thumbnails

The full size images are stored in a container named images. You need another container to store thumbnails of those images.

Ensure you are still signed in to the Cloud Shell (bash). If not, select Enter focus mode to open a Cloud Shell window.

Create a new container named thumbnails in your storage account with public access to all blobs.

Create a blob-triggered serverless function

A trigger defines how a function is invoked. The function you create next uses a blob trigger: the function is automatically invoked when a blob (image file) is uploaded to the images container. A function must have one trigger. Triggers have associated data, which is usually the payload that triggered the function.

Bindings define how a function reads or writes data in Azure or third-party services. This function creates a thumbnail version of the image that triggers it and saves the thumbnail in a thumbnails container.

Open your function app in the Azure Portal.

In the function app window's left hand navigation, hover over Functions and click + to start creating a new serverless function. If a quickstart page appears, click Custom function to see a list of function templates.

Find the BlobTrigger template and select it.

Use these values to create a function that creates thumbnails as images are uploaded.

Setting

Suggested value

Description

Language

C# or JavaScript

Choose your preferred language.

Name your function

ResizeImage

Type this name exactly as shown so the application can discover the function.

Path

images/{name}

Execute the function when a file appears in the images container.

Storage account information

AZURE_STORAGE_CONNECTION_STRING

Use the environment variable previously created with the connection string.

Click Create to create the function.

When the function is created, click Integrate to view its trigger, input, and output bindings.

Click New output to create a new output binding.

Select Azure Blob Storage and click Select. You may have to scroll down to see the Select button.

Enter the following values.

Setting

Suggested value

Description

Blob parameter name

thumbnail

The function uses the parameter with this name to write the thumbnail.

Use function return value

No

Path

thumbnails/{name}

The thumbnails are written to a container named thumbnails.

Storage account connection

AZURE_STORAGE_CONNECTION_STRING

Use the environment variable previously created with the connection string.

JavaScript

(JavaScript) Click on Advanced editor in the top right corner of the window to reveal the JSON representing the bindings.

(JavaScript) In the blobTrigger binding, add a property named dataType with a value of binary. This configures the binding to pass the blob contents to the function as binary data.

(C#) Select the ResizeImage function name on the left navigation to open the function's source code.

(C#) The function requires a NuGet package called ImageResizer to generate the thumbnails. NuGet packages are added to C# functions using a project.json file. To create the file, click View Files on the right to reveal the files that make up the function.

(C#) Click Add to add a new file named project.json.

(C#) Copy the contents of /csharp/ResizeImage/project.json into the newly created file. Save the file. Packages are automatically restored when the file is updated.

Summary

In this module, you created a serverless function to create a thumbnail whenever an image is uploaded to a Blob storage container. Next, you learn how to use Azure Cosmos DB to store and list image metadata.

Store image metadata with Azure Cosmos DB

45 minutes remaining

Azure Cosmos DB is Microsoft's serverless, globally distributed, multi-model database. In this module, you learn how to use Azure Functions to store and retrieve image metadata as JSON documents in Cosmos DB.

Create a Cosmos DB account, database, and collection

A Cosmos DB account is an Azure resource that contains Cosmos DB databases.

Ensure you are still signed into the Cloud Shell. If not, select Enter focus mode to open a Cloud Shell window.

Create a Cosmos DB account with a unique name in the same resource group as the other resources in this tutorial.

Save a document to Cosmos DB when a thumbnail is created

The Cosmos DB output binding lets you create documents in a Cosmos DB collection from Azure Functions. In the following steps, you configure a Cosmos DB output binding in the ResizeImage function and modify the function to return a document (object) to be saved.

Open the function app in the Azure Portal.

In the left hand navigation, expand the ResizeImage function, and then select Integrate.

Under Outputs, click New Output.

Find the Azure Cosmos DB item and select it. Then click Select.

Fill out the fields under Azure Cosmos DB output with the following values.

Click Save. Check the logs panel to ensure the function is successfully saved and there are no errors.

Create a function to list images from Cosmos DB

The web application requires an API to retrieve image metadata from Cosmos DB. In the following steps. you create an HTTP triggered function that uses a Cosmos DB input binding to query the database collection.

In your function app, hover over Functions on the left and click + to create a new function.

Find the HttpTrigger template and select it.

Use these values to create a function that generates a get images URL.

Setting

Suggested value

Description

Name your function

GetImages

Type this name exactly as shown so the application can discover the function.

Authorization level

Anonymous

Allow the function to be accessed publicly.

Click Create.

When the new function is created, click Integrate under the function's name on the left navigation.

Click New Input and select Azure Cosmos DB.

Click Select.

Fill out the following values:

Setting

Suggested value

Description

Document parameter name

documents

Matches parameter name in the function.

Database name

imagesdb

Collection name

images

SQL query

select * from c order by c._ts desc

Get documents, latest documents first.

Azure Cosmos DB account connection

Select existing connection string

Click Save to create the input binding.

C#

Click the function's name to open the code window, and then replace all of run.csx with the content in /csharp/GetImages/run.csx.

Click Save. Check the logs panel to ensure the function is successfully saved and there are no errors.

Test the application

Open the application in a browser. Select an image file and upload it.

After a few seconds, the thumbnail of the new image appears on the page.

In the Azure portal, use the Search box to search for your Cosmos DB account by name. Click it to open it.

Click Data Explorer on the left to browse collections and documents.

Under the imagesdb database, select the images collection.

Confirm that a document was created for the uploaded image.

Summary

In this module, you learned how to create a Cosmos DB account, database, and collection. You also learned how to use the Cosmos DB bindings to save and retrieve image metadata in the Cosmos DB collection. Next, you learn how to automatically generate a caption for each uploaded image using Microsoft Cognitive Services.

Add image captions with Computer Vision

30 minutes remaining

At this point, the application is a functional gallery that allows you to upload and view images. In this module, you learn how to use the Computer Vision API from Microsoft Cognitive Services to generate captions for uploaded images and save the captions with the image metadata in Cosmos DB.

Create a Computer Vision account

Microsoft Cognitive Services is a collection of services available to developers to make their applications more intelligent. The Computer Vision API is a serverless service that processes images using advanced algorithms and returns information about each image. It has a free tier that provides up to 5000 API calls per month.

Ensure you are still signed into the Cloud Shell. If not, select Enter focus mode to open a Cloud Shell window.

Create a new Cognitive Services account of kind ComputerVision with a unique name in your resource group. For the free tier, use F0 as the SKU. If you already have an existing Computer Vision account, you may need to create a Standard account (S1); however, this may incur some costs.

(JavaScript) This function requires the axios package from npm to make an HTTP call to the Computer Vision API. To install the npm package, click on the Function App's name on the left navigation and click Platform features.

(JavaScript) Click Console to reveal a console window.

(JavaScript) Run the command npm install axios in the console. It may take a minute or two to complete the operation.

Click Save. Check the logs panel to ensure the function is successfully saved and there are no errors.

Test the application

Open the application in a browser. Select an image file, and upload it.

After a few seconds, the thumbnail of the new image should appear on the page. Hover over the image to see the description generated by Computer Vision.

Summary

In this module, you learned how to automatically generate captions for each uploaded image using Microsoft Cognitive Services Computer Vision API. Next, you learn how to add authentication to the application using Azure App Service Authentication.