In this part, we will use Azure Static Web Apps to host our client side that consume Azure Functions that we have built. I suggest you to install Azure Static Web Apps CLI. Azure Static Web Apps CLI will help you to develop your apps before it will be deployed. Other tools that I recommend to install:
- Azure Functions CLI
- Azure CLI - Optional
I just want to remind what we've built in previous part. Our final architecture will be like this.
Azure Static Web Apps
I use React.js
for my client side. I'm sorry I can't bring the step by step, since it will be complex and will take long pages.
bervProject / azure-function-example
Azure Function Example in .NET
azure-function-example
Azure Function Example in .NET
Directory Structure
- azure-functions: Root directory for Azure Functions of Backend that will be hosted at Azure Functions. Using .NET 6.
- azure-function-client: Root directory for client to consume Azure Functions and will be hosted at Azure Static Web App Service. Using React.js.
- ToDo.Web: Root directory that consume the Backend from Azure Functions, run as Web App and will be hosted at Azure Web App Service. Using .NET 6.
Contribute
Please see at CONTRIBUTING.md
License
MIT
Author
Bervianto Leo Pratama
Try the app in the local
- Open new terminal. Go to
azure-functions
directory. Runfunc start --csharp
.
- Open new terminal. Go to
azure-function-client
, runswa start http://localhost:3000 --run "yarn start" --api-location http://localhost:7071
- Your app is ready! Don't forget to update some configs. You can see at section.
Notes
You need to make sure to change:
-
msalConfig.ts
import * as msal from "@azure/msal-browser";
export const msalConfig: msal.Configuration = {
auth: {
clientId: '562c2405-0be6-4dcd-9172-e9fc6c681d17' // update this with your client id,
authority: 'https://login.microsoftonline.com/7c3aa68f-b3a1-415a-aa62-a6a97d4a12fc' // update this with your tenant id
}
};
export const loginRequest = {
scopes: [
"openid",
"email",
"profile",
"562c2405-0be6-4dcd-9172-e9fc6c681d17/user_impersonation" // update this with your client id too
],
};
- Update
App.tsx
// another code ...
const getNote = useCallback(() => {
instance.acquireTokenSilent(loginRequest).then(result => {
const accessToken = result.accessToken;
console.log(accessToken);
// update the URL with your azure function URL
axios.get("https://af-demo-berv-1.azurewebsites.net/api/GetToDoTrigger", {
headers: {
'Authorization': `Bearer ${accessToken}`
}
}).then(response => {
console.log(response.data);
setNoteData(response.data);
}).catch(error => {
console.error(error);
})
}).catch(err => {
console.error(err);
});
}, [instance, setNoteData]);
const addNote = useCallback(() => {
if (isHaveActiveAccount && message && title) {
instance.acquireTokenSilent(loginRequest).then(result => {
const accessToken = result.accessToken;
console.log(accessToken);
// update the URL with your azure function URL
axios.post("https://af-demo-berv-1.azurewebsites.net/api/CreateToDoTrigger", {
message,
title
}, {
headers: {
'Authorization': `Bearer ${accessToken}`
}
}).then(response => {
console.log(response);
setOpen(false);
getNote();
Promise.resolve();
}).catch(error => {
console.error(error);
Promise.reject(error);
})
}).catch(err => {
console.error(err);
Promise.reject(err);
});
} else {
Promise.reject("Un-authorized or not fill data");
}
}, [isHaveActiveAccount, message, title, instance, getNote, setOpen]);
// another code ...
I still research about the Authentication. I'm not sure why personal account can't give the access token correctly. So I will get Unauthorized when access it, I need to use my Azure user account to access it. :(
Why you didn't use Azure Functions from Azure Static Web Apps? <- Not have any opinion, just want to separate it. :) I just "simulate" myself like some years ago before Azure Static Web Apps was released. I hope I will have enough time to write up about that too.
Short Video the Setup & Deployment Process
Thank you
Thank you for reading. Anyway, my code is still messy and I will try to update it next year. Stay tune!
Top comments (0)