|
| 1 | +--- |
| 2 | +title: Add an API to Azure Static Web Apps with Azure Functions |
| 3 | +description: Get started with Azure Static Web Apps by adding a Serverless API to your static web app using Azure Functions. |
| 4 | +services: static-web-apps |
| 5 | +author: manekinekko |
| 6 | +ms.service: static-web-apps |
| 7 | +ms.topic: how-to |
| 8 | +ms.date: 05/08/2020 |
| 9 | +ms.author: wachegha |
| 10 | +--- |
| 11 | + |
| 12 | +# Add an API to Azure Static Web Apps Preview with Azure Functions |
| 13 | + |
| 14 | +You can add serverless APIs to Azure Static Web Apps via integration with Azure Functions. This article demonstrates how to add and deploy an API to an Azure Static Web Apps site. |
| 15 | + |
| 16 | +For information about how to secure API routes, refer to the [routing guide](routes.md). |
| 17 | + |
| 18 | +## Prerequisites |
| 19 | + |
| 20 | +- Azure account with an active subscription. [Create an account for free](https://azure.microsoft.com/free). |
| 21 | +- [Visual Studio Code](https://code.visualstudio.com/) |
| 22 | +- [Azure Functions extension](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azurefunctions) for Visual Studio Code |
| 23 | +- [Live Server Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer) extension. |
| 24 | + |
| 25 | +## Create a git repository |
| 26 | + |
| 27 | +The following steps demonstrate how to create a new repository and clone the files to your computer. |
| 28 | + |
| 29 | +1. Navigate to https://github.com/staticwebdev/vanilla-basic/generate to create a new repository. |
| 30 | +1. In the _Repository name_ box, enter **my-vanilla-api**. |
| 31 | +1. Click **Create repository from template**. |
| 32 | + |
| 33 | + :::image type="content" source="media/add-api/create-repository.png" alt-text="Create a new repository from vanilla-basic"::: |
| 34 | + |
| 35 | +Once your project is created, you can use Visual Studio Code to clone the Git repository. |
| 36 | + |
| 37 | +1. Press **F1** to open command in the Command Palette. |
| 38 | +1. Paste the URL into the _Git: Clone_ prompt, and press **Enter**. |
| 39 | + |
| 40 | + :::image type="content" source="media/add-api/vscode-git-0.png" alt-text="Clone a GitHub project using Visual Studio Code"::: |
| 41 | + |
| 42 | + :::image type="content" source="media/add-api/github-clone-url.png" alt-text="Clone a GitHub project using Visual Studio Code"::: |
| 43 | + |
| 44 | + |
| 45 | +## Create your local project |
| 46 | + |
| 47 | +In this section, you use Visual Studio Code to create a local Azure Functions project. Later, you publish the Functions app to Azure. |
| 48 | + |
| 49 | +1. Inside the _my-vanilla-api_ project, create a sub-folder named **api**. |
| 50 | + |
| 51 | + > [!NOTE] |
| 52 | + > You can give this folder any name. This example uses `api`. |
| 53 | +
|
| 54 | +2. Press **F1** to open the Command Palette |
| 55 | +3. Type **Azure Functions: Create New Project...** |
| 56 | +4. Press **Enter** |
| 57 | +5. Choose **Browse** |
| 58 | +6. Select the **api** folder as the directory for your project workspace |
| 59 | +7. Choose **Select** |
| 60 | + |
| 61 | + :::image type="content" source="media/add-api/create-azure-functions-vscode-1.png" alt-text="Create a new Azure Functions using Visual Studio Code"::: |
| 62 | + |
| 63 | +8. Provide the following information at the prompts: |
| 64 | + |
| 65 | + - _Select a language for your function project_: Choose **JavaScript** |
| 66 | + - _Select a template for your project's first function_: Choose **HTTP trigger** |
| 67 | + - _Provide a function name_: Type **GetMessage** |
| 68 | + - _Authorization level_: Choose **Anonymous**, which enables anyone to call your function endpoint. |
| 69 | + - To learn about authorization levels, see [Authorization keys](../azure-functions/functions-bindings-http-webhook-trigger.md#authorization-keys). |
| 70 | + |
| 71 | +9. Using this information, Visual Studio Code generates an Azure Functions project with an HTTP trigger. |
| 72 | + - You can view the local project files in Visual Studio Code's explorer window. |
| 73 | + - To learn more about files that are created, see [Generated project files](https://docs.microsoft.com/azure/azure-functions/functions-develop-vs-code#generated-project-files). |
| 74 | + |
| 75 | +10. Your app should now have a project structure similar to this example. |
| 76 | + |
| 77 | + ```files |
| 78 | + ├── api |
| 79 | + │ ├── GetMessage |
| 80 | + │ │ ├── function.json |
| 81 | + │ │ ├── index.js |
| 82 | + │ │ └── sample.dat |
| 83 | + │ ├── host.json |
| 84 | + │ ├── local.settings.json |
| 85 | + │ ├── package.json |
| 86 | + │ └── proxies.json |
| 87 | + ├── index.html |
| 88 | + ├── readme.md |
| 89 | + └── styles.css |
| 90 | + ``` |
| 91 | +
|
| 92 | +11. Next, update the `GetMessage` function under _api/GetMessage/index.js_ with the following code. |
| 93 | +
|
| 94 | + ```JavaScript |
| 95 | + module.exports = async function (context, req) { |
| 96 | + context.res = { |
| 97 | + body: { |
| 98 | + text: "Hello from the API" |
| 99 | + } |
| 100 | + }; |
| 101 | + }; |
| 102 | + ``` |
| 103 | +
|
| 104 | +12. Update the `GetMessage` configuration under `api/GetMessage/function.json` with the following settings. |
| 105 | +
|
| 106 | + ```json |
| 107 | + { |
| 108 | + "bindings": [ |
| 109 | + { |
| 110 | + "authLevel": "anonymous", |
| 111 | + "type": "httpTrigger", |
| 112 | + "direction": "in", |
| 113 | + "name": "req", |
| 114 | + "methods": [ |
| 115 | + "get" |
| 116 | + ], |
| 117 | + "route": "message" |
| 118 | + }, |
| 119 | + { |
| 120 | + "type": "http", |
| 121 | + "direction": "out", |
| 122 | + "name": "res" |
| 123 | + } |
| 124 | + ] |
| 125 | + } |
| 126 | + ``` |
| 127 | + |
| 128 | +With the above settings, the API endpoint is: |
| 129 | +
|
| 130 | +- Triggered with an HTTP request is made to the function |
| 131 | +- Available to all requests regardless of authentication status |
| 132 | +- Exposed via the _/api/message_ route |
| 133 | +
|
| 134 | +## Run the function locally |
| 135 | +
|
| 136 | +Visual Studio Code integrates with [Azure Functions Core Tools](https://docs.microsoft.com/azure/azure-functions/functions-run-local) to let you run this project on your local development computer before you publish to Azure. |
| 137 | +
|
| 138 | +1. Run the function by pressing **F5** to start the Functions app, and the Core Tools output is displayed in the _Terminal_ panel. |
| 139 | +
|
| 140 | +2. If Azure Functions Core Tools isn't already installed, select **Install** at the prompt. |
| 141 | +
|
| 142 | + When the Core Tools are installed, your app starts in the _Terminal_ panel. As a part of the output, you can see the URL endpoint of your HTTP-triggered function running locally. |
| 143 | +
|
| 144 | + :::image type="content" source="media/add-api/create-azure-functions-vscode-2.png" alt-text="Create a new Azure Functions using Visual Studio Code"::: |
| 145 | +
|
| 146 | +3. With Core Tools running, navigate to the following URL to execute a `GET` request. |
| 147 | +
|
| 148 | + <http://localhost:7071/api/message> |
| 149 | +
|
| 150 | + A response is returned, which looks like the following in the browser: |
| 151 | +
|
| 152 | + :::image type="content" source="media/add-api/create-azure-functions-vscode-3.png" alt-text="Create a new Azure Functions using Visual Studio Code"::: |
| 153 | +
|
| 154 | +After you've verified that the function runs correctly, you can call the API from the JavaScript application. |
| 155 | +
|
| 156 | +### Call the API from the application |
| 157 | +
|
| 158 | +[!INCLUDE [static-web-apps-local-proxy](../../includes/static-web-apps-local-proxy.md)] |
| 159 | +
|
| 160 | +
|
| 161 | +#### Update files to access the API |
| 162 | +
|
| 163 | +1. Next, update the content of the _index.html_ file with the following code to fetch the text from the API function and display it on the screen: |
| 164 | +
|
| 165 | + ```html |
| 166 | + <!DOCTYPE html> |
| 167 | + <html lang="en"> |
| 168 | +
|
| 169 | + <head> |
| 170 | + <meta charset="UTF-8"> |
| 171 | + <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| 172 | + <link rel="stylesheet" href="styles.css"> |
| 173 | + <title>Vanilla JavaScript App</title> |
| 174 | + </head> |
| 175 | +
|
| 176 | + <body> |
| 177 | + <main> |
| 178 | + <h1>Vanilla JavaScript App</h1> |
| 179 | + <p>Loading message from the API: <b id="name">...</b></p> |
| 180 | + </main> |
| 181 | +
|
| 182 | + <script> |
| 183 | + (async function() { |
| 184 | + let { text } = await( await fetch(`/api/message`)).json(); |
| 185 | + document.querySelector('#name').textContent = text; |
| 186 | + }()) |
| 187 | + </script> |
| 188 | + </body> |
| 189 | +
|
| 190 | + </html> |
| 191 | + ``` |
| 192 | + |
| 193 | + With Core Tools running, use the [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer) Visual Studio Code extension to serve the _index.html_ file and open it a in browser. |
| 194 | + |
| 195 | +2. Press **F1** and choose **Live Server: Open with Live Server**. |
| 196 | + |
| 197 | + :::image type="content" source="media/add-api/create-azure-functions-vscode-4.png" alt-text="Create a new Azure Functions using Visual Studio Code"::: |
| 198 | + |
| 199 | + > [!NOTE] |
| 200 | + > You can use other HTTP servers or proxies to serve the `index.html` file. Accessing the `index.html` from `file:///` will not work. |
| 201 | +
|
| 202 | +### Commit and push your changes to GitHub |
| 203 | + |
| 204 | +Using Visual Studio Code, commit and push your changes to the remote git repository. |
| 205 | + |
| 206 | +1. Pressing **F1** to open the Command Palette |
| 207 | +1. Type **Git: Commit All** |
| 208 | +1. Add a commit message |
| 209 | +1. Type in **Git: push** |
| 210 | + |
| 211 | +## Create a static web app |
| 212 | + |
| 213 | +:::image type="content" source="media/add-api/create-static-app-on-azure-portal-1.png" alt-text="Create static app on the Azure portal - screen 1"::: |
| 214 | + |
| 215 | +1. Navigate to the [Azure portal](https://portal.azure.com) |
| 216 | +1. Click **Create a Resource** |
| 217 | +1. Search for **Static Web Apps** |
| 218 | +1. Click **Static Web Apps (Preview)** |
| 219 | +1. Click **Create** |
| 220 | +1. Select your _Azure subscription_ |
| 221 | +1. Select or create a new _Resource Group_ |
| 222 | +1. Name the app **my-vanilla-api**. |
| 223 | +1. Select _Region_ closest to you |
| 224 | +1. Select the **Free** _SKU_ |
| 225 | +1. Click the **Sign-in with GitHub** button and authenticate with GitHub |
| 226 | +1. Select your preferred _Organization_ |
| 227 | +1. Select **my-vanilla-api** from the _Repository_ drop-down |
| 228 | +1. Select **master** from the _Branch_ drop-down |
| 229 | +1. Click the **Next: Build >** button to edit the build configuration |
| 230 | + |
| 231 | +:::image type="content" source="media/add-api/create-static-app-on-azure-portal-2.png" alt-text="Create static app on the Azure portal - screen 2"::: |
| 232 | + |
| 233 | +Next, add the following the build details. |
| 234 | + |
| 235 | +1. Enter **./** for the _App location_. |
| 236 | + |
| 237 | +1. Enter **api** in the _Api location_ box. |
| 238 | + |
| 239 | + This is the name of the API folder created in the previous step. |
| 240 | + |
| 241 | +1. Clear the default value out of the _App artifact location_, leaving the box empty. |
| 242 | + |
| 243 | +1. Click **Review + create**. |
| 244 | + |
| 245 | +| Setting | Description | Required | |
| 246 | +| -------- | ----------------------- | |
| 247 | +| App location | The location of the static application source code | Yes | |
| 248 | +| Api location | The location of the API backend. This points to the root folder of the Azure Functions App project | No | |
| 249 | +| App artifact location | The location of of the build output folder. Some front-end JavaScript frameworks have a build step that places production files in a folder. This setting points to the build output folder. | No | |
| 250 | + |
| 251 | +:::image type="content" source="media/add-api/create-static-app-on-azure-portal-3.png" alt-text="Create static app on the Azure portal - screen 3"::: |
| 252 | + |
| 253 | +1. Click **Create** |
| 254 | +1. Wait for deployment to finish (this may take a minute) |
| 255 | +1. Navigate to `https://github.com/<YOUR_GITHUB_ACCOUNT>/my-vanilla-api/actions?query=workflow%3A"Azure+Pages+CI%2FCD"` |
| 256 | +1. Make sure the build is successful |
| 257 | + |
| 258 | +:::image type="content" source="media/add-api/github-workflow-0.png" alt-text="GitHub Workflow"::: |
| 259 | + |
| 260 | +The deployed API will be available at `https://<STATIC_APP_NAME>.azurestaticapps.net/api/<FUNCTION_OR_ROUTE_NAME>`. |
| 261 | + |
| 262 | +:::image type="content" source="media/add-api/github-workflow-1.png" alt-text="GitHub Workflow"::: |
| 263 | + |
| 264 | +You can also find the application URL from the Azure portal: |
| 265 | + |
| 266 | +:::image type="content" source="media/add-api/static-app-url-from-portal.png" alt-text="Access static app URL from the Azure portal"::: |
| 267 | + |
| 268 | +Alternatively you can directly access your Azure Static Web App at `https://<STATIC_APP_NAME>.azurestaticapps.net` and check the result in the browser. |
| 269 | + |
| 270 | +## Clean up resources |
| 271 | + |
| 272 | +If you don't want to keep this application for further use, you can use the following steps to delete the Azure Static Web App and its related resources. |
| 273 | + |
| 274 | +1. Navigate to the [Azure portal](https://portal.azure.com) |
| 275 | +1. In the top search bar, type **Resource groups** |
| 276 | +1. Click **Resource groups** |
| 277 | +1. Select **myResourceGroup** |
| 278 | +1. On the _myResourceGroup_ page, make sure that the listed resources are the ones you want to delete. |
| 279 | +1. Select **Delete** |
| 280 | +1. Type **myResourceGroup** in the text box |
| 281 | +1. Select **Delete**. |
| 282 | + |
| 283 | + |
| 284 | +## Next steps |
| 285 | + |
| 286 | +> [!div class="nextstepaction"] |
| 287 | +> [Configure app settings](./application-settings.md) |
0 commit comments