Overview

With the recent updates to the [serverless-azure-functions](https://github.com/serverless/serverless-azure-functions/blob/master/CHANGELOG.md) plugin, it is now easier than ever to create, deploy and maintain a real-world REST API running on Azure Functions. This post will walk you through the first few steps of doing that.

To see the full end-to-end example used to create this demo, check out my GitHub repo. I structured each commit to follow the steps described in this post. Any steps named Step X.X are steps that involve no code or configuration changes (and thus not tracked by source control), but actions that could/should be taken at that point in the process. This is done to preserve the “commit-per-step” structure of the example repo.

This post will only cover the basics of creating and deploying a REST API with Azure Functions, which includes step 1 and step 2 from the example repo. Stay tuned for posts on the additional steps in the future.

I will make the assumption that you have the Serverless Framework installed globally. If you do not (or have not updated in a while), run:

npm i serverless -g

Also, the serverless CLI can be referenced by either serverless or sls. I will use sls in this post just because it’s shorter, but serverless would work just the same.

Step 1: Create your local Azure Function project

Let’s begin by creating our Azure Function project with a template from serverless.

sls create -t azure-nodejs -p sls-az-func-rest-api

The resulting project will be in the directory sls-az-func-rest-apicd into that directory and run npm install. To make sure you have the latest version of the Azure Functions plugin, run:

npm install serverless-azure-functions --save

It’s important to note that the generated serverless.yml file will contain a lot of commented lines, which start with #. Those are purely for your benefit in exploring features of the Azure Functions plugin, and can be safely removed.

Step 2: Add your own handlers

For the sake of this demo, we’re going to create a basic wrapper of the GitHub API for issues and pull requests.

As you’ve probably already noticed, the azure-nodejs template comes preloaded with two functions: hello and goodbye. Let’s remove those before we start adding our own code. To do this, remove both the hello.js and goodbye.js files. Also, remove their configuration definitions from serverless.yml.

Right now your file structure should look something like:

sls-az-func-rest-api
|-- host.json
|-- package.json
|-- README.md
|-- serverless.yml

and your serverless.yml should look like (not including any comments):

1
service: sls-az-func-rest-api 
2

3
provider:
4
  name: azure
5
  location: East US
6
  runtime: nodejs10.x
7

8
plugins:
9
  - serverless-azure-functions
10

11
package:
12
  exclude:
13
    - local.settings.json
14
    - .vscode/**
15

16
functions:
Add Code

Let’s add in our own code. We’ll start by creating the directory src/handlers. This, perhaps to your great surprise, will be where our handlers will live. Inside that directory, we will put our two handlers: issues.js and pulls.js.

1
// src/handlers/issues.js
2

3
const utils = require("../utils");
4
const axios = require("axios");
5

6
module.exports.handler = async (context, req) => {
7
  context.log("Issue Handler hit");
8

9
  const owner = utils.getQueryOrBodyParam(req, "owner");
10
  const repo = utils.getQueryOrBodyParam(req, "repo");
11

12
  if (owner && repo) {
13
    const response = await axios({
14
      url: `https://api.github.com/repos/${owner}/${repo}/issues`,
15
      method: "get"
16
    });
17
    context.res = {
18
      status: 200,
19
      body: response.data
20
    };
21
  } else {
22
    context.res = {
23
      status: 400,
24
      body: "Please pass the name of an owner and a repo in the request"
25
    };
26
  }
27
};
1
// src/handlers/pulls.js
2

3
const utils = require("../utils");
4
const axios = require("axios");
5

6
module.exports.handler = async (context, req) => {
7
  context.log("Pull Request Handler hit");
8

9
  const owner = utils.getQueryOrBodyParam(req, "owner");
10
  const repo = utils.getQueryOrBodyParam(req, "repo");
11

12
  if (owner && repo) {
13
    const response = await axios({
14
      url: `https://api.github.com/repos/${owner}/${repo}/pulls`,
15
      method: "get"
16
    });
17
    context.res = {
18
      status: 200,
19
      body: response.data
20
    };
21
  } else {
22
    context.res = {
23
      status: 400,
24
      body: "Please pass the name of an owner and a repo in the request"
25
    };
26
  }
27
};

#api #serverless

How to Create a REST API with Azure Functions and the Serverless Framework - Part 1
3.15 GEEK