Backend development on Azure Functions with TypeScript

Burak Tasci
Apr 7, 2018 · 6 min read

Serverless architecture is without a doubt one of the hottest topics in cloud computing, allowing developers to build and run apps and services without thinking about the servers actually running the code as well as significantly reducing operational costs.

Image for post
Image for post

When we initiated a new project a few months ago, I decided to adopt this micro-services model — developing the back-end as a small series of services, each running independently and communicating through HTTP requests.

Then, I had to choose the server-side programming language to develop our backend.

Candidates were C#, TypeScript and Go

Except the last candidate, me and my team were able to work efficiently.

Image for post
Image for post

Go was something completely new, and I was considering it for the performance outcomes — it’s lightning FAST. However, there’re no cloud platform providing native support, and getting Go work with wrappers is a total nightmare. Furthermore, package storage is quite distributed (mainly on git repositories) — may lead to missing dependencies.

Go was eliminated.

Well, before making this choice we compared the three major cloud platforms in terms of languages supported, self-manageability and integration with CI processes so that developers could take the responsibility of the DevOps role.

Image for post
Image for post

The ease of management of functions was something extremely convenient about Azure — compared to AWS’s painstaking processes, as well as Github integration.

I chose Azure over AWS.

Me and the majority of my team were coming from strongly-typed languages like Java/C#, and the project was requiring us to join into full-stack roles.

After a set of discussions, I found out that the use of TypeScript was the best choice: as for being a typed language (without explicitly introducing abstractions), for the syntax allowing us to leverage our Java/C# knowledge to the backend, and its use on the Angular platform — being a full-stack solution.

Since TypeScript is a superset JavaScript, it’s easy to transpile it into JavaScript with a simple build setup (Webpack) and host it on Azure Functions platform — and I chose TypeScript over C# for all the reasons mentioned above.

In praise of TypeScript

Image for post
Image for post

Getting started

Enough background, in this article I’m going to walk through how to create a RESTful backend on Azure Functions with TypeScript.

First things first, we need to install the azure-cli to be able to self-host and debug the function apps:

npm install -g azure-cli

As we got the azure-cli running on our development machine, let’s fork the sample repository that I prepared as a reference:

git clone https://github.com/azure-seed/azure-functions-typescript

Now, you should be able to notice our sample function ./src/some-function and its contents (function settings, the function itself and its specs).

If you have a look at the ./tools directory, you’ll notice the build and deployment scripts. Because the Azure Functions portal doesn’t actually support TypeScript, we gottta handle the compilation into JavaScript. Webpack and UglifyJS are our best friends at this point.

So we have all the tooling needed!

Build steps

The build steps and deployment configuration can all be found the azure-seed/azure-functions-typescript repository. Running the following npm commands will compile our function app and generate the output at the ./dist directory and run the function

# dev build
npm run build:dev
Image for post
Image for post

The ./dist dist folder contains all the files (host.json, local.settings.json, and function output) to be hosted on the Azure Functions environment. In order to test run the function, you can run the following npm commands.

Image for post
Image for post
# run the function locally (azure-cli)
cd dist
func run f

At this point, I assume you’ve got Postman installed on your environment. There’re actually other HTTP testing tools that you can use — but I strongly recommend anyone to stick to Postman.

Testing the function

Let’s perform the following sample request:

GET http://localhost:7071/api/some-function
Image for post
Image for post

The sample request should return you the following result with the status code of HTTP 200 (OK).

HTTP 200
{
object: "list",
data: [
{
id: "57ade20771e59f422cc652d9",
object: "someObject",
name: "Azure"
}
],
hasMore: false,
totalCount: 1
}

At this point, we got a working backend

Under the hood

The ./src/some-function/some-function.ts file describes a simple RESTful backend which allows to simulate CRUD operations.

It exports a function named run, which routes the request to the default controller using the GET, POST, PATCH, and DELETE.

export function run(context: Context, req: HttpRequest): any {
let res: HttpResponse;
const id = req.params
? req.params.id
: undefined;
switch (req.method) {
case HttpMethod.Get:
res = id
? getOne(id)
: getMany(req);
break;
case HttpMethod.Post:
res = insertOne(req);
break;
case HttpMethod.Patch:
res = updateOne(req, id);
break;
case HttpMethod.Delete:
res = deleteOne(id);
break;
default:
res = {
status: HttpStatusCode.MethodNotAllowed,
body: {
error: {
type: 'not_supported',
message: `Method ${req.method} not supported.`
}
}
};
}
context.done(undefined, res);
}

To build your codebase out more declarative, easier to maintain and reusable, you may benefit from the azure-seed/azure-functions-ts-essentials project — containing the essential interfaces such as HttpMethod, HttpRequest, HttpResponse, HttpStatusCode.

Image for post
Image for post

Azure Functions TS Essentials is the best shorthand around

Last but not least, but there already are two more projects to significantly reduce the amount of boilerplate code (from establishing the connection, to route the requests to the relevant methods and returning the result/result set — ensuring the request payload is formed well) required to implement data access layers for MongoDB and Elasticsearch: azure-functions-mongooser and azure-functions-elasticizer.

I’d love to include more details about the those projects, but it would actually exceed the scope of this article. Soon, you should be hearing about them too on this publication — stay tuned!

Automatic deployment

In this seed, we used Circle-CI (circle.yml here) to run the build tasks and unit tests (using JEST testing framework) before pushing the output files to the prod branch.

Image for post
Image for post

Using the Azure Functions console (located in the Platform Features -> Deployment Options of the function app) and setting the automatic deployment settings to use the prod branch.

Image for post
Image for post

Go ahead, make my day!

We got our function developed in TypeScript, compiled to JavaScript and automatically deployed to Azure Functions on every push (while build & test succeed) via CI

…now this is a force to be reckoned with!

Burak Tasci (fulls1z3)
https://www.linkedin.com/in/buraktasci
http://stackoverflow.com/users/7047325/burak-tasci
https://github.com/fulls1z3

Burak Tasci

In depth articles about software technologies

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store