Hi, Developers! Today I would like to teach you how we can migrate to version 4 of the Node.js programming model for Azure Functions, using a real case project: Contoso Real Estate.
Join us for Hack Together: JavaScript on Azure Global Hack from Aug 16 - 31, 2023
Get ready to dive into a world of innovation and growth as we embark on an exciting journey together. Today, I'm thrilled to guide you through an essential skill that will not only enhance your development prowess but also open doors to limitless possibilities in the tech realm.
Imagine you're not just learning about the latest trends, but actively applying them to a real-world project that could transform industries. Intrigued? Let's talk about migrating to version 4 of the Node.js programming model for Azure Functions, and we're doing it in style with a remarkable project: Contoso Real Estate.
This isn't just another tutorial; this is your chance to be part of something bigger. Brace yourselves as we uncover the magic of version 4 and its game-changing potential. But wait, there's more! This knowledge aligns seamlessly with the Hack Together Program: JavaScript on Azure Global Hack – a platform that celebrates innovation, collaboration, and pushing the boundaries of what's possible.
You're not just learning lines of code; you're shaping the future, one function at a time. Imagine the thrill of contributing to projects that might just redefine how we perceive real estate, how we interact with technology, and how we elevate user experiences.
Still curious? Excited? I know I am! Join us for the Hack Together: JavaScript on Azure Global Hack, an event that's not just a date on the calendar but a chance to immerse yourself in a world of innovation. From August 16 to 31, 2023, mark your presence in a community of like-minded developers, thinkers, and creators who dare to dream big.
So, are you ready to turn your curiosity into code, your ideas into impact, and your skills into success? Let's unlock the doors to version 4, amplify our abilities, and make Contoso Real Estate more than just a project – let's make it a testament to what student entrepreneurial developers like you can achieve.
Get ready to code, collaborate, and conquer. The future of tech is in your hands, and together, we're about to redefine what's possible.
Stay curious, stay innovative, and let's Hack Together!
Hi, friends! Are you curious about Azure Functions v4 for Node? Let me tell you all about it!
Azure Functions v4 is the latest version of the Node.js programming model for Azure Functions. It comes with a bunch of new features and improvements, such as:
Flexible folder structure
Being able to define function.json directly in the function's in the code
New HTTP trigger types
Improved IntelliSense
Timer Trigger (TypeScript)
Durable Functions (TypeScript)
Migrating from v3 to v4 is necessary to take advantage of these new features and improvements as well as the new features of latest versions of the Node.js runtime. However, it's important to note that v4 is still in preview. It is not yet recommended for production use and should be tested for correct behavior in development environments.
Microsoft offers a comprehensive guide to help migrate from v3 to v4 complete with tips and best practices to help you with the migration process, covering topics like:
Some important considerations
Requirements to make the migration
How to enable the v4 programming model
How to
Include the npm package
And set up the app entry point
How to define the function in code
The new usage of context
Review the usage of HTTP types
Let's take dive in and see that process with a real app! Let's try this with our Contoso Real Estate Reference Sample
3. About Contoso Real Estate Reference Application
The Contoso Real Estate Reference App is a sample application that demonstrates how to build a real estate website using Azure services in a composable architecture fashion. The app is constructed using a variety of technologies, including TypeScript, Node.js, and the frameworks Angular, Next.js and payment technologies like Stripe. The app includes features such as property listings, property details, and property search. The app also includes an admin portal for managing properties and users.
We then use a selected set of Azure serverless services to deploy to and run the app. Azure Functions plays a key role in the Contoso Real Estate Reference App by providing the backend APIs. The app uses an OpenAPI spec to define the API, and Azure Functions are used to implement the API endpoints. One benefit of using Azure Functions for the API is that it provides fully managed serverless capabilties, which means that you only pay for the compute resources that you use. One challenge of using Azure Functions for the API is that you need to ensure that your functions are secure and scalable.
For this article, we will migrate only one function from the Contoso Real Estate API to version 4, as it would not be possible to migrate all of them in a single article. The project has has several functions like this -- if you want to see the whole migration process end-to-end, bookmark and watch my Contoso Real Estate API YouTube playlist.
This has a series of 10 videos that cover migration of all functions
The videos are in Portuguese but should give you a frame of reference to follow along.
The function migration we will be covering in this article is get-users
note: I made 10 videos (in Portuguese) explaining how I did the entire project API. If you want to watch, just access the playlist: Contoso Real Estate API.
2️⃣ | 👉🏽 Create a new branch in project
Let's use Codespaces! Since it comes with the default development environment pre-defined, it is easier and faster to jumpstart our development without having to set things up ourselves.
note: Codespaces offers free 60 hours per month, renewed on a monthly basis. Whenever you stop using the resource, you must turn off Codespaces to avoid unwanted consumption.
I created a development environment for this migration using Codespaces and consequently created a new branch called GL/content-v3-to-v4. If you want to do the same, feel free. And now inside the packages folder create a folder called api-v4.
Let's go to the steps to migrate the function.
To follow this migration, I will be using the Visual Studio Code extension: Azure Functions. This extension allows us to create an Azure Functions project quickly and easily. To do this, just click on the Azure Functions icon in the Visual Studio Code sidebar and click the Create New Project button.
Then click on: Browse and select the api-v4 folder that we created earlier.
Choose the option: TypeScript
Choose the option: Model V4 (Preview)
Choose the option: HTTP trigger and consequently name the trigger as: users
If you want to follow the step by step, just see the gif below:
3️⃣ | 👉🏽 Create a new folder for v4 refactor
Once you have created the project, note in the api-v4 folder the new folder structure of the new Node.js programming model for Azure Functions.
Notice that we now have a folder called src and inside it we have a folder called functions and inside it we have the file called users.ts. This file is our HTTP trigger that we created earlier.
Much less 'polluted' than version 3, isn't it? In which each function had its own folder and inside it had the index.ts file and the function.json.
Did you notice another detail? The function.json file no longer exists. Now, we can define using app.http or app.get within our code.
src/functions/index.ts
import{app,HttpRequest,HttpResponseInit,InvocationContext}from"@azure/functions";exportasyncfunctionusers(request:HttpRequest,context:InvocationContext):Promise<HttpResponseInit>{context.log(`Http function processed request for url "${request.url}"`);constname=request.query.get('name')||awaitrequest.text()||'world';return{body:`Hello, ${name}!`};};app.http('users',{methods:['GET','POST'],authLevel:'anonymous',handler:users});
Also note the package.json file:
package.json
{"name":"api-v4","version":"1.0.0","description":"","scripts":{"build":"tsc","watch":"tsc -w","clean":"rimraf dist","prestart":"npm run clean && npm run build","start":"func start","test":"echo \"No tests yet...\""},"dependencies":{"@azure/functions":"^4.0.0-alpha.7"},"devDependencies":{"@types/node":"^18.x","typescript":"^4.0.0","rimraf":"^5.0.0"},"main":"dist/src/functions/*.js"}
Please, note that the @azure/functions package is in version 4.0.0-alpha.7. This is because version 4 is still in preview. And, as we are using TypeScript, there is a property called main that points to the *.js file inside the dist/src/functions folder. Later we will make a small change to this file.
To test and see if the function is working, just run the command: npm start, Codespaces will ask you to open the browser. At the end of the URL put: /api/users. If the phrase: Hello World appears, it is because it is working correctly.
See the step by step in the gif below:
4️⃣ | 👉🏽 Migration get-users (v3 function) to users (v4)
note: the Contoso Real Estate project API makes use of Azure Cosmos DB. If you don't know, I recommend that you read the documentation. It is a globally distributed, multi-model, NoSQL database and multi-API. In this case here, the MongoDB API is being used and consequently the ORM Mongoose. Let's assume that you have already copied the files related to the database for your migration of the new version of the Azure Functions programming model and that we are only now migrating the functions, okay?
Now that we have the project structure, let's migrate the get-users (v3) function to users (v4). Open the users.ts file and let's start the migration.
src/functions/users.ts
import{HttpRequest,HttpResponseInit,InvocationContext}from"@azure/functions";import{findUsers}from"../models/user";// GET: All usersexportasyncfunctiongetUsers(request:HttpRequest,context:InvocationContext):Promise<HttpResponseInit>{context.log(`Http function getUsers processed request for url "${request.url}"`);constoffset=Number(request.query.get("offset"))||0;constlimit=Number(request.query.get("limit"))||10;if (offset<0){return{status:400,jsonBody:{error:"Offset must be greater than or equal to 0",},};}elseif (limit<0){return{status:400,jsonBody:{error:"Limit must be greater than or equal to 0",},};}elseif (offset>limit){return{status:400,jsonBody:{error:"Offset must be less than or equal to limit",},};}try{constusers=awaitfindUsers({offset,limit});if (users){return{jsonBody:users,};}else{return{status:404,jsonBody:{error:"Users not found",},};}}catch (error){return{status:500,jsonBody:{error:"Internal Server Error",},};}};app.http('users',{methods:['GET','POST'],authLevel:'anonymous',handler:getUsers});
Probably you will see an error in app.http, because I intentionally removed the call from app at the beginning of the file. Now comes a small change. To make the project more organized, let's create a file inside the src folder called: index.ts. This file will be responsible for importing all the functions of the project and exporting to the main ofpackage.json.
Remove the app.http block contained in the users.ts file and paste it into the index.ts file. Then, import the getUsersfunction and export it.
Notice that, instead of using app.http, we use app.get. This is because, this method specifically will be handling the HTTP verb GET.
In the new Azure Functions programming model, the HTTP verbs are:
app.get
app.post
app.put
app.patch
app.deleteRequest
And, finally go to the package.json file and change the main property to: dist/src/index.js.
If you want to create a POST, for example, just use the app.post method and so on. And, there in the users.ts file just include the logic related to the HTTP verb POST.
What does this mean? The project structure will be more: concise, simple and very similar to what is already used in Express.js.
Now let's run the project! Run the command: npm start and open the browser. At the end of the URL put: /api/users. In this case, as I am not with the database, it will return an error. But, if you have the database, it will return the registered users or according to the API you will be using.
If you want to see the entire project's api migration, there is an open Pull Request to see the migrated apis.
We just migrated a v3 Azure Functions app to the new v4 Functions programming model for Node.js, in a few simple steps.
Let's summarize what we learned today:
the key differences between Azure Functions v3 and v4 programming models for Node.js
how to create a new Azure Functions v4 app from scratch
the new model is simpler and more concise (no need for a file per function!)
The specific file changes for this migration can be found in this Pull Request on the Contoso Real Estate application repository. Browse it to get an understanding of the design decisions made and challenges faced when trying to migration a complex project at scale!
Contributions Welcome
And, feel free to make contributions to the project. There is a list of good first issues** that you can contribute to.
Intelligent enterprise-grade reference architecture for JavaScript, featuring OpenAI integration, Azure Developer CLI template and Playwright tests.
page_type
languages
products
urlFragment
name
description
sample
azdeveloper
javascript
typescript
nodejs
bicep
azure
azure-container-apps
azure-container-registry
azure-cosmos-db
azure-database-postgresql
azure-functions
azure-key-vault
azure-sdks
azure-storage
static-web-apps
entra-id
playwright
vs-code
azure-pipelines
contoso-real-estate
Contoso Real Estate: JavaScript + Enterprise
Intelligent enterprise-grade reference architecture for JavaScript, featuring OpenAI integration, Azure Developer CLI template and Playwright tests.
Enterprise-grade Reference Architecture for JavaScript
This repository contains the reference architecture and components for building enterprise-grade modern composable frontends (or micro-frontends) and cloud-native applications. It is a collection of best practices, architecture patterns, and functional components that can be used to build and deploy modern JavaScript applications to Azure.
Important
The application code is meant to serve as a reference. Please incorporate your security governance, audits and conventions before productionizing.
Supported Application Scenarios
The following scenarios are part of the application sample