Get Started with Azure Functions(V4) in Node.js & TypeScript
Azure Functions is a serverless compute service that lets you run small pieces of code (called functions) without managing servers. You only write the logic, and Azure automatically handles scaling, execution, and infrastructure. This makes it ideal for building APIs, background jobs, event-driven automation, and microservices using a pay-only-for-use model. It is similar to lambda functions in AWS.
🚀 What You Will Learn
In this Blog, you’ll learn:
- How to set up Azure Functions on your local machine
- How to create a Function project using Node.js + TypeScript
- How to run and test the function locally
- How to deploy it to Azure
⚙️ Step 1: Installing azure tools
Install the Azure Functions CLI (skip if already installed):
npm i -g azure-functions-core-tools🛠️ Step 2: Initializing Project
Run this command to setup the project:
func init --typeScript✨ Step 3: Defining functions
Azure Functions are created using the func new command.To create a new function, run:
func newChoose the option:
HTTP triggerAfter selecting Http trigger, name the function as helloWorld.
This creates:
src/functions/helloWorld.tsUnderstanding the code, the below snippet is a simple Hello World code that supports both GET and POST methods.
File: src/functions/index.ts
import { app, HttpRequest, HttpResponseInit, InvocationContext } from '@azure/functions';
export async function helloWorld(
request: HttpRequest, // incoming request (method, headers, query, body)
context: InvocationContext, // provides logging + metadata about the function run
): Promise<HttpResponseInit> {
// Logging inside Azure Functions — visible in the terminal and Azure logs
context.log(`Http function processed request for url "${request.url}"`);
const name = request.query.get('name') || (await request.text()) || 'world';
// Return a simple text response back to the client
return { body: `Hello, ${name}!` };
}
app.http('helloWorld', {
methods: ['GET', 'POST'],
authLevel: 'anonymous',
handler: helloWorld,
});To run the functions:
npm run start🔐 Step 4: Setting up ENVIRONMENT VARIABLES
File: local.settings.json
{
"IsEncrypted": false,
"Values": {
"FUNCTIONS_WORKER_RUNTIME": "node",
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"DATABASE_URL": "VALUE"
}
}The ENVIRONMENT VARIABLES can be accessed using process.env.VARIABLE_NAME.
🏗️ Step 5: Building a simple CRUD API
Follow this folder structure...
your-project/
├── src/
│ ├── functions/
│ │ └── books.ts
│ ├── handlers/
│ │ └── books.ts
│ ├── utils/
│ │ └── try-catch.ts
│ └── index.ts
├── host.json
├── local.settings.json
├── package.json
├── tsconfig.json
└── node_modules/File: src/utils/try-catch.ts
Creating a utility function for error handling.
import { HttpResponseInit } from '@azure/functions';
export async function TryCatch(promise: Promise<HttpResponseInit>): Promise<HttpResponseInit> {
try {
return await promise;
} catch (error) {
return {
status: 500,
jsonBody: {
jsonBody: {
message: 'Internal Server Error',
error: (error as Error)?.message ?? 'Unknown error',
},
},
};
}
}File: src/functions/books.ts
Creating a new function book to handle CRUD operations for books.
import { app, HttpRequest, HttpResponseInit, InvocationContext } from '@azure/functions';
import { createBooks, deleteBooks, editBooks, getBooks } from '../handlers/books';
import { TryCatch } from '../utils/try-catch';
export async function booksHandler(
request: HttpRequest,
context: InvocationContext,
): Promise<HttpResponseInit> {
if (request.method === 'GET') return TryCatch(getBooks());
if (request.method === 'POST') return TryCatch(createBooks(request));
if (request.method === 'PUT') return TryCatch(editBooks(request));
if (request.method === 'DELETE') return TryCatch(deleteBooks(request));
return { status: 405, jsonBody: { message: 'Method Not Allowed' } };
}
app.http('books', {
route: 'books/{id?}',
authLevel: 'anonymous',
methods: ['GET', 'POST', 'PUT', 'DELETE'],
handler: booksHandler,
});File: src/handlers/books.ts
Creating handlers for books operations.
import { HttpRequest, HttpResponseInit } from '@azure/functions';
import { Book } from '../types';
export async function getBooks(): Promise<HttpResponseInit> {
let books = [];
//fetch books from database
return { status: 200, jsonBody: { data: books } };
}
export async function createBooks(request: HttpRequest): Promise<HttpResponseInit> {
const body = (await request.json()) as Book;
if (!body.title || !body.author)
return { status: 400, jsonBody: { message: 'Title and Author are required fields' } };
// create books in database
return { status: 200, jsonBody: { message: 'Book Created Successfully', data: newBook } };
}
export async function editBooks(request: HttpRequest): Promise<HttpResponseInit> {
const id = request.params.id;
if (!id || isNaN(Number(id)))
return { status: 400, jsonBody: { message: 'Book ID is required' } };
const body = (await request.json()) as Book;
if (!body.title || !body.author)
return { status: 400, jsonBody: { message: 'Title and Author are required fields' } };
// update book in database
return { status: 200, jsonBody: { message: 'Book Updated Successfully' } };
}
export async function deleteBooks(request: HttpRequest): Promise<HttpResponseInit> {
const id = request.params.id;
if (!id || isNaN(Number(id)))
return { status: 400, jsonBody: { message: 'Book ID is required' } };
// delete book from database
return { status: 200, jsonBody: { message: 'Book Deleted Successfully' } };
}🚀 Step 6: Deployment
Login to your Azure account:
az loginCreate a resource group:
az group create --name <RESOURCE_GROUP_NAME> --location <REGION>Create a storage account:
az storage account create --name <STORAGE_ACCOUNT_NAME> --resource-group <RESOURCE_GROUP_NAME> --location <REGION> --sku Standard_LRSCreate a Function App:
az functionapp create \
--resource-group <RESOURCE_GROUP_NAME> \
--consumption-plan-location <REGION> \
--runtime node \
--runtime-version 20 \
--functions-version 4 --name <FUNCTION_APP_NAME> \
--storage-account <STORAGE_ACCOUNT_NAME>Create a Function App:
npm run buildDeploy your Function App:
func azure functionapp publish <FUNCTION_APP_NAME>📦 Conclusion
With this, you now have a clear and basic understanding of how to build and deploy a Function in Azure. From setting up your project to creating your first trigger and pushing it live, you’ve covered the essential steps needed to get started with serverless development. As you explore further, you can build on this foundation with advanced triggers, integrations, and real-world use cases. Azure Functions is a powerful tool, and the more you practice, the more confident you’ll become in leveraging its capabilities. Keep exploring new patterns, try connecting different Azure services, and continue refining your workflow. Keep experimenting, keep building — thanks for reading, I hope it was useful, and have a great day ❤️
Checkout the full code here.