Page Type | Languages | Key Services | Tools |
---|---|---|---|
Sample | .NET JavaScript (Node.js, React.js) PowerShell |
Azure API Management Azure Functions Azure App Service |
GitHub Actions |
This sample codebase demonstrates how to deploy APIs written in .NET to Azure App Service and Azure Function Apps, and abstract them behind an Azure API Management gateway. A React.js web application is used to demonstrate calling the APIs.
The motivation behind this guide is to provide a basic structure to get up and running quickly with API Management in Azure.
This sample references existing approaches documented by Microsoft, namely:
Azure API Management is a solution that enables abstraction, security, observability, discovery, and consumption of API assets in an Azure-first, hybrid, or multicloud environment.
The solution presented in this codebase is simple and should be viewed as a foundation for modification and expansion into more complex applications.
- An Azure Subscription - for hosting cloud infrastructure
- Az CLI - for deploying Azure infrastructure as code
- Azure Functions Core Tools and Azurite - for testing Functions locally
- .NET 6.0 - for .NET development
- Node.js - for Node.js development
- (Optional) A GitHub Account - for deploying code via GitHub Actions
- Register a new application
- Create a new client secret - you will use this if you choose to automate the deployment of the application using GitHub Actions
- Add the desired resource names in
devops/config/variables.json
. - Run the script
devops/scripts/integration/function.ps1
. - This will create the Function App instance, in addition to all of the related components including a Storage Account, App Insights, and an App Service Plan.
- Add the desired resource names in
devops/config/variables.json
. - Run the script
devops/scripts/api/api.ps1
. - This will create an API Management and App Service instance, in addition to an App Service Plan if not already created.
- Add the desired resource names in
devops/config/variables.json
. - Run the script
devops/scripts/client/client.ps1
. - This will create an App Service instance, in addition to an App Service Plan if not already created.
- To deploy to Azure using GitHub Actions, a handful of credentials are required for connection and configuration. In this example, they will be set as Actions Secrets. For each of the below secrets, the secret name and steps on how to populate the secret is provided.
-
AZURE_SP_CREDENTIALS
:- A JSON object that looks like the following will need to be populated with 4 values:
{ "clientId": "<GUID>", "clientSecret": "<STRING>", "subscriptionId": "<GUID>", "tenantId": "<GUID>" }
- You can find more details on creating this secret here.
- For clientId, run:
az ad sp list --display-name <service principal name> --query '[].[appId][]' --out tsv
- For tenantId, run:
az ad sp show --id <clientID> --query 'appOwnerOrganizationId' --out tsv
- For subscriptionId, run:
az account show --query id --output tsv
- For clientSecret: This is the client secret created alongside the App Registration above
- Note: This section will discuss deployment of the codebase via GitHub Actions. If you choose not to deploy via GitHub Actions, you may opt to manually deploy the code by following the automated tasks or with another CI/CD tool - the steps will be the same.
-
Deploy the Function App by updating the branch trigger in the
.github/workflows/function-cicd.yml
file to trigger the GitHub Action.- This will publish, package, and deploy the .NET 'ApiFunction' to the above deployed Function App.
-
Deploy the web API to App Service by updating the branch trigger in the
.github/workflows/web-api-cicd.yml
file to trigger the GitHub Action.- This will build, publish, and deploy a web API to the API App Service deployed above.
-
Set up the APIs and Product:
-
In the Azure Portal, navigate to the API Management resource, choose the 'APIs' blade, and scroll down to 'Create from Azure resource'. Follow these guides to import the resources you created as APIs (accept the defaults):
- Import Azure Function App as an API
- Import Azure App Service as an API
- You may need to add the App Service URL in the 'Web service URL' setting of the App Service API after importing it if you're seeing an HTTP 500 - Internal Server Error as described here.
-
In the Azure Portal, navigate to the API Management resource, choose the 'Products' blade, and follow this guide to create a product:
- Create and publish a product
- When creating the product, add the APIs that you just created.
- Create and publish a product
-
To test the React app locally, you may consider adding a CORS policy for the APIs you created. A policy which allows all origins can be found at
devops/scripts/api/cors-policy.xml
.
-
-
Deploy the web client to App Service by updating the branch trigger in the
.github/workflows/client-cicd.yml
file to trigger the GitHub Action.- This will build and deploy the React app to the web App Service deployed above.
- After deploying, you will need to configure the startup command.
In the Azure Portal, open the App Service, and in the Configuration blade, choose the 'General settings' tab, and set the Startup Command as
pm2 serve /home/site/wwwroot --no-daemon
. - The deployment script assumes that the default values were accepted when importing the Function and App Service into API Management in the previous step. If any customizations were made, the 'Variable replacement' task in the GitHub Action will need to be modified.
A diagram visually describing the flow of code from local development to GitHub to Azure, and the way the components communicate in Azure.
- The Function's
/ApiFunction
endpoint returns a simple string, and the Web API exposes a/Hello
endpoint, which also returns a simple string. The end user invokes these endpoints by calling their abstracted endpoint via API Management.- In the UI, the user is prompted to provide an API key. The return values of these endpoints are printed to the page once execution is complete.
- To get a Subscription key, navigate to the API Management service in the Azure Portal and open the 'Subscriptions' blade. Choose either the Primary or Secondary key for the Product that you created above.
- Although the client application was created as a demonstration of calling the APIs via JavaScript, you may use any utility to call the APIs, including the built-in testing tool in the Azure Portal.
Since this codebase demonstrates a basic setup, several additional steps can be taken to configure the architecture for production. Some of the main considerations are listed below.
- Restrict traffic to only be routed through APIM
- As set up in this tutorial, the backend services communicate with API Management, but are still available on the internet. In a production scenario, you should restrict access to the backends so that traffic is only routed via the API Management instance. There are a variety of ways to achieve this, some of them being:
- Import additional APIs
- APIs can be imported from a variety of backend types, including Azure Kubernetes Service, Logic Apps, or as one-off HTTP endpoints.
- OpenAPI 3 APIs can be easily imported as described here.
- Authentication and authorization
- API Management has various authentication and authorization mechanisms available to secure user access to features and APIs.
- You can integrate API Management with Azure Active Directory via OAuth or AD B2C.
- Create API revisions and versions
- Create policies
- You may add policies to inbound and outbound requests to control things like rate limiting, transforming headers, caching, validating JWT tokens, etc.
- Scaling up
- The Consumption and Developer tiers may be appropriate for prototyping and evaluating the service, whereas the Standard and Premium tiers are intended for production usage, with more features to handle larger workloads. By default, this example uses the Developer tier.
- See more about the available tiers and features here.
- There are several practical use cases for using Azure API Management, some of which include:
- Using an API gateway to secure and manage access to backend services.
- Having an API developer portal to easily onboard developers and publish API documentation.
- Enforcing usage quotas and rate limits to ensure that only authorized users have access to the API.
- Transforming incoming and outgoing data for better compatibility with other services.
- Leveraging out-of-the-box policies for authentication, authorization, and rate limiting.