A cloud-native app needs a frontend for your users to work with. Here’s how to configure an Azure App Service and then create and deploy a TypeScript/JavaScript client-side React frontend to that App Service using Visual Studio code.
In previous posts, I’ve created a Web Service that securely accessed an Azure SQL database (Part 5). The next obvious step is to create a frontend for that Web Service and then secure access between that frontend and the Web Service.
In this post, I’m going to cover the first part of that: creating a client-side frontend in React in Visual Studio Code and deploying it to an Azure App Service (there’s a companion post to this one that does the same for a server-side ASP.NET Core frontend (Part 7b). In a follow-on post, I’ll restrict the Web Service to only talk to this authorized frontend.
The first step in creating a client-side app is to use a scaffolding tool to create the skeleton of your project. I’m showing that I’m hip, with it and up to date by using Vite to create my React app before opening the app in Visual Studio Code:
<name of your frontend app>
with the name you want to give your frontend app (I used WarehouseMgmtFrontendReact
). After hitting Enter, you’ll be asked to confirm your package name which will be your app name in lowercase. Just hit Enter again to continue:npx create-vite@latest <name of your frontend app> --template react-ts
cd <name of your project>
code .
Your next step is to write the code to access your Web Service. In Visual Studio Code, in the Explorer pane on the left, expand the src node and double click the App.tsx file to open it. Delete all the code in the file and replace it with some minimal code to demonstrate that you’ve successfully called your Web Service.
I used the following code, flagging places where you’ll need to tweak to work with your service (and, hopefully, you’ll also use more appropriate variable and function names than my “Product”-related names):
import { useEffect, useState } from "react";
//replace with properties from your objects
type Product =
{
productId: number,
name: string,
listPrice: number
}
function App()
{
//replace Product with the name of your type
const [products, setProducts] = useState<Product[]>([]);
useEffect(
() => {
const loadProducts = async () =>
{
//replace "products" with the URL extension for your method
await callWarehouseManagementService("products");
}
loadProducts();
},
[]
)
const WarehouseMgmtDomain: string = "<replace with your App Service's domain>";
const callWarehouseManagementService = async (target:string) =>
{
let res = await fetch("https://" + WarehouseMgmtDomain + "/" + target);
if (res.ok) { setProducts(await res.json()); }
};
return (
<>
{products.map(
(prd:Product) => {
return(
<>
<p>
{/* replace with property names from your type */}
Product Id: {prd.productId} <br/>
Product Name: {prd.name} <br/>
Product Price: {prd.listPrice} <br/>
</p>
</>
)
} )
}
</>
)
}
export default App
Now you need to build your app. Save your code (unless you have auto-save turned on in Visual Studio Code, in which case, your code is already saved). From Visual Studio Code’s Terminal menu, select New Terminal to open a terminal pane below your code pane. In the newly opened Terminal pane, type npm run build to check that you don’t have any coding errors.
After cleaning up any coding errors (and saving your file after making those changes), you’re ready to deploy your app.
The first step in deploying your app to Azure is to create an App Service. You can do this from within Visual Studio Code, but I think using Azure Portal’s UI helps understand what’s going on. So what follows is a cut-down version of the steps from my earlier post on creating an App Service (Part 3) that uses the Azure Portal and is modified for a Node.js app.
After surfing to the App Services page in the Azure portal, click on the + Create at the left end of the menu at the top of the page and select Web App to start the Create Web App wizard.
As with any Azure resource, you’ll need to assign your App Service to a resource group and give it a name (the App Service’s name gets rolled into a URL so you can’t use spaces, though this page will let you use upper case letters).
By default, the Wizard will automatically tack a random string at the end of the name so that the resulting URL is unique, but you can turn that off using the toggle switch right below your App Service’s name (I called my service WarehouseMgmtFrontEnd
, for example, which turned out to be unique).
To support my frontend, I set the Code/Container radio button to Code (check out that earlier post for a discussion around picking the Container choice). Picking the Code option displays the Runtime stack dropdown that lets you pick what support stack for your application will be loaded into the App Service. I picked Node 20 LTS because it matched the version of Node.js installed on the computer where I created my React app (you can determine what version of Node you’re using by opening a Command Prompt and executing node -v). For the operating system, I picked Windows because that was the platform I was developing on.
I set the Region to the same region as the Azure SQL database I created in my previous post, Coding Azure 2: Configuring an Azure SQL Database, to avoid any cross-region charges (that’s Canada Central, in my case).
Following those selections are the choices that let you set how much processing power you’ll get (and, as a result, how much you’ll pay). Under Pricing Plan, I clicked on Create New and, in the resulting dialog, gave my plan a name.
When you return from assigning your plan a name, you’ll have a dropdown list of available plans. For this sample application, I selected the Free F1 plan which gives me 60 processing minutes a day to play with. In real life, you’ll probably need more processing power than that.
On the Monitoring + secure Tab, I disabled Application Insights because I didn’t want to pay for it.
With those changes made, I clicked the Review + Create button and then the Create button to create my App Service.
Back in Visual Studio Code, you need to add some extensions to support deploying your app to an Azure App Service.
To add those extensions, in Visual Studio Code, click on the Extensions icon in the far left panel (it’s the icon of the square divided into four parts with one part popping out) to open the Extensions panel. In the Search box at the top of the panel, search for the Azure App Service extension and install it. (This should also install the Azure Resources extension, but you might want to search for it in the Extensions pane and confirm that it is installed). A new Azure icon will be added to the panel on the left side of Visual Studio.
You’re now ready to deploy your app:
As your deployment is processing, you’ll be asked if you want to always deploy your project to this App Service. Pick the “Yes” option.
If your deployment succeeds, you’ll get a button that will allow you to Browse Website. Click that button to try viewing your app (you can also right-click on your App Service in the Azure panel on the left and select Browse Website). Don’t be surprised to discover that your app doesn’t work … at least, not yet.
Your app won’t work because the App Service that’s holding your App service is set up to reject requests from apps running in any domain outside of your Web Service’s App Service. To fix that, you’ll need to update the CORS settings for your Web Service’s App Service to accept requests from your frontend’s App Service:
Return to the tab that’s displaying your frontend and refresh the page (you may have to wait a minute or so for your CORS update to propagate).
Your browser should display the information returned from your Web Service. If it doesn’t—don’t panic! It’s entirely possible that your database didn’t respond in time because it was in idle mode. Try some refreshes over a couple of minutes before debugging.
If you picked the “always want to deploy” option on your first deploy, then, when you have the Azure icon selected in Visual Studio Code’s far left menu, you’ll see a Workspace bar displayed in the Azure pane. If you hover your mouse over that bar, you’ll see an App Service icon displayed at the right end of the bar. Clicking that icon will re-execute your deployment so that you don’t have to find your App Service in the Azure pane (you’ll still have to click “Deploy” in the “are you sure” dialog, though).
And, since you are deploying from your app’s dist folder, you have to remember to do a build before deploying so that you’re getting your latest code.
Given all of those steps, it’s worth noting that you don’t have to deploy to Azure in order to test your app, using the npm run dev command in Visual Studio Code’s terminal window will let you run your app on your local computer. You will need to add the URL that your app is using when running locally to the CORS list for the App Service holding your Web Service.
As long as we’re working on our frontend, we should spend a little time thinking about maintainability.
Our frontend will be passing business transactions to a more complex system, probably consisting of multiple steps and/or microservices. When things go wrong in production (and they will), you’ll need to be able to track those business transactions through the various microservices that were supposed to process that transaction.
It makes sense, at this point, to generate a correlation id for every transaction submitted by your frontend that you can hand off to all subsequent processes. Those processes can then incorporate that correlation id in their logs and/or error messages. Having a correlation id for a business transaction be very helpful in figuring out what actually happened to that transaction.
The only real requirement for the correlation id is that it must be unique for each transaction. You could assemble a correlation id from parts of the information associated with the transaction (e.g., date and time down to the millisecond), but, for this case study, I’m going to generate a unique identifier using the Node.js UUID package.
First, in Visual Studio Code’s terminal, window, I’ll install the UUID package to my project:
npm install uuid
At the top of my App.tsx file, I’ll add this import statement to make the most recent version of the UUID processor available to my app (by the time you read this, the most recent version might be something more recent than v6):
import {v6} from 'uuid';
I then update my call to my Web Service to generate a correlation id and pass it to my Web Service in the X-Correlation-ID header of my request:
const correlationid:string = v6();
const callWarehouseManagementService = async (target:string) =>
{
let res = await fetch("https://" + WarehouseMngmntDomain + "/" + target,
{ headers: {'X-Correlation-ID': correlationid} }
);
if (res.ok) { …
In the Web Service, to retrieve the header, you need to accept (as a parameter to your API method) the HttpRequest object that represents the request made to the service. Within your API method, you can use the HttpRequest object’s Headers collection to retrieve the correlation header by name (in this case, the name you want is “X-Correlation-ID”). Once you’ve retrieved the correlation id, it’s up to you how you want to use it.
That means the start of a typical Web API method (with a sample log message that takes advantage of the correlation ID) would look something like this:
app.MapGet("/products", (HttpRequest req) =>
{
string correlationId = req.Headers["X-Correlation-ID"].ToString();
app.Logger.LogInformation("Request received, Correlation Id: " + correlationId);
Your next step is to secure the access between your frontend and your Web Service. That’s my next post (assuming you skip over the “creating an ASP.NET Core frontend” post).
Peter Vogel is both the author of the Coding Azure series and the instructor for Coding Azure in the Classroom. Peter’s company provides full-stack development from UX design through object modeling to database design. Peter holds multiple certifications in Azure administration, architecture, development and security and is a Microsoft Certified Trainer.