Step by Step Guide: Migrating v3 to v4 programming model for Azure Functions for Node.Js Application
Tags: javascript, hacktogether, contosorealestate, webdev
Published: 2023-08-14 13:10:01

---
title: Step by Step Guide: Migrating v3 to v4 programming model for Azure Functions for Node.Js Application
published: true
description: In this article I will show you how to migrate from version 3 to version 4 of the programming model for Azure Functions for Node.Js applications using a real case project Contoso Real Estate
tags: #javascript #hacktogether #contosorealestate #webdev
canonical_url: https://techcommunity.microsoft.com/t5/educator-developer-blog/step-by-step-guide-migrating-v3-to-v4-programming-model-for/ba-p/3897691
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jpewcmsgg46k95iervg4.jpg
# Use a ratio of 100:42 for best results.
# published_at: 2023-06-21 22:06 +0000
---

## Welcome!

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](https://github.com/Azure-Samples/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!

To learn more about:

{% link https://dev.to/azure/join-us-for-hack-together-javascript-on-azure-global-hack-from-aug-16-31-2023-oc7 %}

## 1. What is Azure Functions v4 for Node?

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](https://nodejs.org/)** 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.

Learn more:

- ✅ **[TypeScript](https://learn.microsoft.com/azure/azure-functions/create-first-function-vs-code-typescript?pivots=nodejs-model-v4&WT.mc_id=javascript-104342-gllemos)**
- ✅ **[JavaScript](https://learn.microsoft.com/azure/azure-functions/create-first-function-vs-code-node?pivots=nodejs-model-v4&WT.mc_id=javascript-104342-gllemos)**
- ✅ **[Durable Functions TypeScript](https://learn.microsoft.com/azure/azure-functions/durable/quickstart-ts-vscode?pivots=nodejs-model-v4&WT.mc_id=javascript-104342-gllemos)**
- ✅ **[Durable Functions JavaScript](https://learn.microsoft.com/azure/azure-functions/durable/quickstart-js-vscode?pivots=nodejs-model-v4&WT.mc_id=javascript-104342-gllemos)**
- ✅ **[Free Course: Build Serverless APIs with Azure Functions](https://learn.microsoft.com/training/modules/build-api-azure-functions/?WT.mc_id=javascript-104342-gllemos)**
- ✅ **[Free Course: Deploy serverless APIs with Azure Functions, Logic Apps, and Azure SQL Database](https://learn.microsoft.com/training/modules/deploy-backend-apis/?WT.mc_id=javascript-104342-gllemos)**
- ✅ **[Free Course: Refactor Node.js Express APIs into serverless Azure Functions APIs](https://learn.microsoft.com/training/modules/shift-nodejs-express-apis-serverless/?WT.mc_id=javascript-104342-gllemos)**
- ✅ **[Free Course: Build serverless, full stack applications in Azure](https://learn.microsoft.com/training/paths/build-serverless-full-stack-apps-azure/?WT.mc_id=javascript-104342-gllemos)**
- ✅ **[Free Course: Architect full-stack applications and automate deployments with GitHub](https://learn.microsoft.com/training/modules/automate-deployments-github-actions-azure/?WT.mc_id=javascript-104342-gllemos)**

## 2. Create a _new_ Azure Functions v4 app

Microsoft offers a comprehensive guide to help **[migrate from v3 to v4](https://learn.microsoft.com/en-us/azure/azure-functions/functions-node-upgrade-v4?tabs=azure-cli-set-indexing-flag%2Cv4)** 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](https://aka.ms/contoso-real-estate/github)**

## 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.

Learn more:

- **[Contoso Real Estate Reference Sample Repo](https://aka.ms/contoso-real-estate/github)
- **[Contoso Real Estate Reference Sample Documentation](https://aka.ms/contoso-real-estate/website)
- **[Azure Functions Reference Documentation](https://docs.microsoft.com/azure/azure-functions/?WT.mc_id=javascript-104342-gllemos)

## 4. Let's Migrate The App to Azure Functions v4.

### 1️⃣ | 👉🏽 Identify the target function(s)

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](https://www.youtube.com/playlist?list=PLb2HQ45KP0Wu6g_B-QJrvWOe8RdNCmio2)** 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](https://github.com/Azure-Samples/contoso-real-estate/tree/main/packages/api/get-users)**

[![Screen-Shot-08-07-23-at-07-41-PM.png](https://i.postimg.cc/4dtXKcyG/Screen-Shot-08-07-23-at-07-41-PM.png)](https://postimg.cc/2bzsMVn9)

> **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](https://www.youtube.com/playlist?list=PLb2HQ45KP0Wu6g_B-QJrvWOe8RdNCmio2).

### 2️⃣ | 👉🏽 Create a new branch in project

Let's use **[Codespaces!](https://github.com/features/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.

1. To follow this migration, I will be using the Visual Studio Code extension: **[Azure Functions](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azurefunctions)**. 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.

2. Then click on: **Browse** and select the `api-v4` folder that we created earlier.

3. Choose the option: **TypeScript**

4. Choose the option: **Model V4 (Preview)**

5. 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:

[![v4-function-users.gif](https://i.postimg.cc/4dLxtcRF/v4-function-users.gif)](https://postimg.cc/BLF3fX6x)

### 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.

[![Screen-Shot-08-07-23-at-08-21-PM.png](https://i.postimg.cc/LXpNFqq5/Screen-Shot-08-07-23-at-08-21-PM.png)](https://postimg.cc/t1Bhh4NG)

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

```typescript
import { app, HttpRequest, HttpResponseInit, InvocationContext } from "@azure/functions";

export async function users(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
    context.log(`Http function processed request for url "${request.url}"`);

    const name = request.query.get('name') || await request.text() || 'world';

    return { body: `Hello, ${name}!` };
};

app.http('users', {
    methods: ['GET', 'POST'],
    authLevel: 'anonymous',
    handler: users
});
```

Also note the `package.json` file:

* package.json

```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:

[![execution-function-v4.gif](https://i.postimg.cc/2SPfvxtt/execution-function-v4.gif)](https://postimg.cc/gxq5b3my)

### 4️⃣ | 👉🏽 Migration `get-users` (v3 function) to `users` (v4)

> **note**: the Contoso Real Estate project API makes use of **[Azure Cosmos DB](https://azure.microsoft.com/services/cosmos-db/?WT.mc_id=javascript-104342-gllemos)**. 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](https://mongoosejs.com/)**. 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

```typescript
import { HttpRequest, HttpResponseInit, InvocationContext } from "@azure/functions";
import { findUsers } from "../models/user";

// GET: All users
export async function getUsers(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
  context.log(`Http function getUsers processed request for url "${request.url}"`);

  const offset = Number(request.query.get("offset")) || 0;
  const limit = Number(request.query.get("limit")) || 10;

  if (offset < 0) {
    return {
      status: 400,
      jsonBody: {
        error: "Offset must be greater than or equal to 0",
      },
    };
  } else if (limit < 0) {
    return {
      status: 400,
      jsonBody: {
        error: "Limit must be greater than or equal to 0",
      },
    };
  } else if (offset > limit) {
    return {
      status: 400,
      jsonBody: {
        error: "Offset must be less than or equal to limit",
      },
    };
  }

  try {
    const users = await findUsers({ 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` of` package.json`.

Remove the `app.http` block contained in the `users.ts` file and paste it into the `index.ts` file. Then, import the `getUsers` `function` and export it.

* src/index.ts

```typescript
app.http('users', {
  methods: ['GET', 'POST'],
  authLevel: 'anonymous',
  handler: getUsers
});
```

* src/index.ts

```typescript
import { app } from "@azure/functions";
import { getUsers } from "./functions/users";

app.get('get-users', {
  route: 'users',
  authLevel: 'anonymous',
  handler: getUsers
});
``` 

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.

[![final-execution-v4.gif](https://i.postimg.cc/L8X1hjYw/final-execution-v4.gif)](https://postimg.cc/Tpzw4LcJ)

> If you want to see the entire project's api migration, there is an open Pull Request to see the migrated apis.

{% github https://github.com/Azure-Samples/contoso-real-estate/pull/231 %}

## Conclusion

🎉 Congratulations! 

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](https://github.com/Azure-Samples/contoso-real-estate/pull/231)** 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](https://github.com/Azure-Samples/contoso-real-estate/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)** that you can contribute to.

{% github Azure-Samples/contoso-real-estate %}

I hope you enjoyed it and see you next time!

And, happy coding! 🚀🚀🚀