Blog Post

Apps on Azure Blog
5 MIN READ

New API backend options in Azure Static Web Apps

anninakeller's avatar
anninakeller
Icon for Microsoft rankMicrosoft
Jun 21, 2022

Integrate APIs hosted on Azure App Service, Azure Container Apps, and Azure API Management

 

 

Frontend web applications often rely on dynamic content retrieved from APIs. Azure Static Web Apps supports seamless integration with Azure Functions to create serverless HTTP APIs. Azure Functions is one of several popular options for hosting APIs on Azure. Today, we’re excited to announce Azure Static Web Apps has added preview support for integrating APIs in the following Azure services:

 

 

You can link any of these resources to your static web app’s production or named preview environments. When linked, any requests to a route prefixed with /api is routed to your backend resource. Using a linked backend allows your frontend app to call your API without configuring cross-origin resource sharing (CORS), and it enables Static Web Apps Authentication to work seamlessly and securely with your API. 

 

To learn more, check out the documentation and try the tutorial below.

 

Walk-through — Azure Static Web Apps integration with Azure Container Apps

 

Objective: Create an end-to-end authenticated app

 

Adding authentication and authorization to a backend service can be a real pain point 🥵. Azure Static Web Apps makes this easy by providing built-in authentication using providers like GitHub and Azure Active Directory. You can use it to protect both your frontend app and your linked backend APIs.

 

Static Web Apps allows you to integrate with APIs hosted in other services such as Azure Container Apps. When a backend resource is integrated with a static web app, it's configured to accept requests exclusively from the static web app (you can change it to allow other traffic). If an end user is logged in with one of the configured identity providers, Static Web Apps adds an X-MS-CLIENT-PRINCIPAL header to every backend API request that contains information about the user and their roles. This allows you to use authentication in your backend APIs without writing any code.

 

Sample: Azure Static Web Apps + Azure Container Apps

 

Let's look at an example. It's a simple voting app.

 

Create a Static Web Apps resource

 

For our example, we'll first create a simple React app using the react-basic starter template on GitHub.

 

After creating the GitHub project using the template, we'll deploy it to a new static web app. To integrate with Azure Container Apps, we'll need to create an Azure Static Web Apps resource using the Standard plan. You can use the the Azure portal. It will take a couple of minutes for the app to deploy.

 

Create a backend resource

 

In addition to the static web app, we'll also need a backend to serve as an API. For this example, I chose to create a scalable app using Azure Container Apps. Container Apps is a serverless platform that's great for running many types of containerized workloads, including web apps, background tasks, and microservices.

 

The app I deployed is a Node.js app in a container. It exposes an endpoint at /api/vote — simply returning a response containing {"message": "successfully submitted vote"}. You can deploy a container app with my Docker image (anninakeller/simple-survey:latest) by following these instructions.

 

Make sure to enable an external ingress on your container app and define the target port as 3000

 

It's important that our HTTP API has the /api prefix contained in the path since only APIs with that prefix will be available to the static web app.

 

 
Test your container app to make sure the endpoint is working.
 

Link our two resources

 

Now we can go back to the Static Web Apps resource we created in the Azure portal and open the APIs tab. We'll see all the environments that we created for our app. For now, there should only be one. Click the Link button for the Production environment. Select Container Apps as the backend resource type and then the subscription and resource name of the container app we just created. Then click Link to integrate this container app as our static web app's API backend.

 

 

Fetch content from our API in our React app

 

Now we need to adjust our React code to actually make a call to our linked API that is now accessible at /api/vote on our static web app. Lets add this very simple code to our App.js file.

import React from 'react';

function sendVote() {
  fetch('/api/vote')
    .then(response => response.json())
    .then(json => alert(json.text));
}

function App() {
  return (
    <div className="App">
      <button onClick={sendRequest}>Vote</button>
    </div>
  );
}

export default App;
Push the code to GitHub and wait for GitHub Actions to finish deploying the changes.
 
 
The updated code sends an API request to the endpoint /api/vote whenever the Vote button is clicked, which in our case should send a request to our backend service and then alert the response text, "successfully submitted vote," as defined in our container image.
 
Once Linked APIs are activated for a Static Web Apps resource all requests containing the /api prefix will be forwarded to the backend service.
 

Let's test it

 
When we now go to the our static web app and press the Vote button, we will send the request to our linked API and alert the returned text.
 

 
The API request is forwarded from your static web app to the container app. The container app is not directly accessible. To view or modify its accessibility, open its Authentication tab in the Azure portal.

 

Add some routing rules

 
To make this scenario more useful, let's add some routing rules to our Static Web Apps resource.
 
Add the following routes array to your staticwebapp.config.json file.
{
    "navigationFallback": {
        "rewrite": "/index.html"
    },
    "routes": [
    {
      "route": "/api/vote",
      "allowedRoles": ["authenticated"]
    }
}
This routing rule will forbid any user that is not logged in from accessing the defined route. You can test that by trying it out in your browser. You can also define the route as "/api/*" to prohibit any unauthenticated user from accessing the API.
 
Now, before you can access the backend resource again, you'll need to go to one of the login endpoints and login using one of the predefined identity providers. I am using GitHub, so I navigate to <static-web-apps-default-hostname>/.auth/login/github and login using my GitHub credentials.
 

And TADAAAAAA! We're done! 🪄

 

Restricting access itself can be useful but in some cases you would like to be able to identify the end user as well. This information is passed to the API backend in the X-MS-CLIENT-PRINCIPAL header. To learn how to use it, see Accessing user information.

 

Final GitHub project: https://github.com/annikel/simple-vote-swa

 

To learn more, check out the documentation.

 

Annina Keller is a software engineer on the Azure Static Web Apps team. (Twitter: @anninake)

 
Updated Jul 06, 2022
Version 4.0