Manage serverless APIs with Apache APISIX

Bobur Umurzokov - Jan 18 '23 - - Dev Community

Serverless computing enables developers to build applications faster by eliminating the need for them to manage infrastructure. With serverless APIs in the cloud, the cloud service provider automatically provisions, scales, and manages the infrastructure required to run the code.

This article shows with the simple example how to manage Java-based serverless APIs build with Azure functions. It uses azure-functions plugin to integrate Apache APISIX API Gateway with Azure Serverless Function that invokes the HTTP trigger functions and return the response from Azure Cloud.

Apache APISIX offers additional plugins that can be used with other serverless solutions like AWS Lambda.

Learning objectives

You will learn the following throughout the article:

  • What serverless APIs?
  • The role of API Gateway in managing complex serverless API traffic.
  • How to set up Apache APISIX Gateway.
  • How to build serverless APIs with Azure Functions.
  • How to expose serverless APIs as upstream services.
  • How to secure serverless APIs with APISIX authentication plugins.
  • How to apply rate-limiting policies.

Before we get started with the practical side of the tutorial, let's go through some concepts.

What serverless APIs?

Serverless APIs are the same as traditional APIs, except they utilize a serverless backend. For businesses and developers, serverless computing means they no longer have to worry about server maintenance or scaling server resources to meet user demands. Also, serverless APIs avoid the issue of scaling because they create server resources every time a request is made. Serverless APIs reduce latency because they are hosted on an origin server. Last but not least serverless computing is far more cost-efficient than the traditional alternative such as building entire microservices.

Serverless APIs using Azure function

An Azure Function is a simple way of running small pieces of code in the cloud. You don’t have to worry about the infrastructure required to host that code. You can write the Function in C#, Java, JavaScript, PowerShell, Python, or any of the languages that are listed in the supported languages.

With Azure Functions, you can rapidly build HTTP APIs for your web apps without the headache of web frameworks. Azure Functions is serverless, so you're only charged when an HTTP endpoint is called. When the endpoints aren't being used, you aren't being charged. These two things combined make serverless platforms like Azure Functions an ideal choice for APIs where you experience unexpected spikes in traffic.

API Gateway for Serverless APIs traffic management

An API Gateway is the fundamental part of serverless API because it is responsible for the connection between a defined API and the function handling requests to that API. There are many benefits of API Gateway in the serverless-based APIs architecture. In addition to API Gateway’s Primary edge functionalities such as authentication, rate throttling, observability, caching, and so on, it is capable of invoking serverless APIs, subscribing to events, then processing them using callbacks and forward authentication requests to external authorization services with completely custom serverless function logic.

Manage serverless APIs with Apache APISIX demo

With enough theoretical knowledge in mind, now we can jump into a practical session. We use an example project repo apisix-manage-serverless-apis hosted on GitHub. You can find the source code and sample curl commands we use in this tutorial.

For our mini-project, we’ll work with two simple Azure functions written in Java that simulates our serverless APIs for Product and Review services.

Prerequisites

Set up the project

This first thing you clone the project repo from GitHub:

git clone https://github.com/Boburmirzo/apisix-manage-serverless-apis.git
Enter fullscreen mode Exit fullscreen mode

Open the project folder in your favorite code editor. The tutorial leverages VS Code.

Run Apache APISIX

To run Apache APISIX and Azure functions locally, you can follow these steps:

Open a new terminal window and run docker compose up command from the root folder of the project:

docker compose up -d
Enter fullscreen mode Exit fullscreen mode

Above command will run Apache APISIX and etcd together with Docker. For example, if Docker desktop installed on your machine, you can see running containers there:

Apisix is running on Docker

We installed APISIX on our local environment in this demo but you can also deploy it to Azure and run it on Azure Container Instance. See the following tutorial.

Run Azure functions

Then, navigate to /upstream folder:

mvn clean install
mvn azure-functions:run
Enter fullscreen mode Exit fullscreen mode

The two functions will start in a terminal window. You can request both serverless APIs in your browser:

For example:

Products Serverless API

Reviews Serverless API

Deploy Azure functions

Next, we deploy functions code to Azure Function App by running below cmd:

mvn azure-functions:deploy
Enter fullscreen mode Exit fullscreen mode

Or you can simply follow this tutorial on how to deploy the function project to Azure

Note that the function app name is randomly generated based on your artifactId, appended with a randomly generated number. In the tutorial cmds, the function app name serverless-apis is mentioned.

Just to make sure our function works, we can test an invocation call directly requesting it URL in the browser:

https://serverless-apis.azurewebsites.net/api/products
https://serverless-apis.azurewebsites.net/api/reviews
Enter fullscreen mode Exit fullscreen mode

Exposing serverless APIs in APISIX

Once the set up is complete, now we will expose serverless Azure function APIs as upstream services in APISIX. To do so, we need to create a new Route with azure-function plugin enabled for both products and reviews serverless backend APIs.

If azure-function plugin is enabled on a route, APISIX listens for requests on that route’s path, and then it invokes the remote Azure Function code with the parameters from that request.

Create a Route for Products

To create a route for Products function, run the following command:

curl http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
    "name": "Create a route with Azure function plugin",
    "plugins": {
        "azure-functions": {
            "function_uri": "https://serverless-apis.azurewebsites.net/api/products",
            "ssl_verify": false
        }
    },
    "uri": "/products"
}'
Enter fullscreen mode Exit fullscreen mode

Note that we set ssl_verify attribute of azure-functions plugin to false to disable SSL verification for only the demo purpose. You can also enable it to perform more secure requests from APISIX to Azure Functions. Learn other configuration parameters.

Test With a Curl Request

We can use curl to send a request, seeing if APISIX listens on the path correctly and forwards the request to the upstream service successfully:

curl -i -XGET http://127.0.0.1:9080/products
HTTP/1.1 200 OK
[
  {
    "id": 1,
    "name": "Product1",
    "description": "Description1"
  },
  {
    "id": 2,
    "name": "Product2",
    "description": "Description2"
  }
]
Enter fullscreen mode Exit fullscreen mode

Great! We got response from the actual serverless API on Azure Function.

Next, we will make similar configuration for reviews function.

Create a Route for Reviews and test

Create the second route with Azure function plugin enabled:

curl http://127.0.0.1:9180/apisix/admin/routes/2 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
    "plugins": {
        "azure-functions": {
            "function_uri": "https://serverless-apis.azurewebsites.net/api/reviews",
            "ssl_verify": false
        }
    },
    "uri": "/reviews"
}'
Enter fullscreen mode Exit fullscreen mode

Test serverless API response:

curl -i -XGET http://127.0.0.1:9080/reviews
Enter fullscreen mode Exit fullscreen mode

In this section, we introduced the new route and added azure-functions plugin to our serverless APIs so that APISIX can invoke remote Azure functions and manage the traffic. In the following sections, we will learn how to authenticate API consumers and apply runtime policies like rate-limiting.

Secure serverless APIs with APISIX authentication plugins

Up to now, our serverless APIs are public and accessible by unauthorized users. In this section, we will enable the authentication feature to disallow unauthorized requests to serverless APIs.

Apache APISIX can verify the identity associated with API requests through credential and token validation. Also, it is capable of determining which traffic is authorized to pass through the API to backend services. You can check all available authentication plugins.

Let's create a new consumer for our serverless APIs and add basic-auth plugin for the existing route so that only allowed user can access them.

Create a new consumer for serverless APIs

The below command will create our new consumer with its credentials such as username and password:

curl http://127.0.0.1:9180/apisix/admin/consumers -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
    "username": "consumer1",
    "plugins": {
        "basic-auth": {
            "username": "username1",
            "password": "password1"
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Add basic auth plugin to the existing Products and Services routes.

Now we configure basic-auth plugin for routes to let APISIX check the request header with the API consumer credentials each time APIs are called:

curl http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
    "name": "Create a route with Azure function plugin",
    "plugins": {
        "azure-functions": {
            "function_uri": "https://serverless-apis.azurewebsites.net/api/products",
            "ssl_verify": false
        }, 
        "basic-auth": {}
    },
    "uri": "/products"
}'
Enter fullscreen mode Exit fullscreen mode
curl http://127.0.0.1:9180/apisix/admin/routes/2 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
    "plugins": {
        "azure-functions": {
            "function_uri": "https://serverless-apis.azurewebsites.net/api/reviews",
            "ssl_verify": false
        },
        "basic-auth": {}
    },
    "uri": "/reviews"
}'
Enter fullscreen mode Exit fullscreen mode

Test basic auth plugin

Now if we request the serverless APIs without user credentials in the header, we will get an unauthorized error:

curl -i http://127.0.0.1:9080/products
HTTP/1.1 401 Unauthorized

{"message":"Missing authorization in request"}
Enter fullscreen mode Exit fullscreen mode

The result is as we expected. But if we provide the correct user credentials in the request and access the same endpoint, it should work well:

curl -i -u username1:password1 http://127.0.0.1:9080/products
HTTP/1.1 200 OK
Enter fullscreen mode Exit fullscreen mode

We have validated the client’s identity attempting to request serverless APIs by using basic authentication plugin with the help of Apache APISIX.

Apply rate limiting policies for serverless APIs

In this section, we will protect serverless APIs from abuse by applying a throttling policy. In Apache APISIX Gateway we can apply rate limiting to restrict the number of incoming calls.

Apply and test the rate-limit policy

With the existing route configurations for Products and Reviews functions selected, we can apply a rate-limit policy with limit-count plugin to protect our API from abnormal usage. We will limit the number of API calls to 2 per 60s per API consumer.

To enable limit-count plugin for the existing Products route, we need to add the plugin to plugins attribute in our Json route configuration:

curl http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
    "name": "Create a route with Azure function plugin",
    "plugins": {
        "azure-functions": {
            "function_uri": "https://serverless-apis.azurewebsites.net/api/products",
            "ssl_verify": false
        },
        "basic-auth": {},
        "limit-count": {
            "count": 2,
            "time_window": 60,
            "rejected_code": 403,
            "rejected_msg": "Requests are too frequent, please try again later."
        }
    },
    "uri": "/products"
}'
Enter fullscreen mode Exit fullscreen mode

Apache APISIX will handle the first two requests as usual. However, a third request in the same period will return a 403 HTTP Forbidden code with our custom error message:

HTTP/1.1 403 Forbidden

{"error_msg":"Requests are too frequent, please try again later."}
Enter fullscreen mode Exit fullscreen mode

Next steps

In this article, we learned step by step how to create Java-based serverless APIs with Azure Functions and Apache APISIX Gateway to manage your APIs throughout their full lifecycle from the exposing serverless APIs as upstream services in APISIX to properly secure and apply rate-limiting to limit the number of requests. This opens the doors to other use-cases of API Gateway and serverless APIs integration.

You can explore other capabilities of APISIX Gateway by chaining of various built-in plugins to transform requests, monitor the availability, performance, and usage of our serverless APIs, cache API responses and further evolve them by versioning APIs that helps you to reduce development time, increase scalability, and cost savings.

Apache APISIX is fully open-source API Gateway solution. If you require to have more advanced API management features for serverless APIs, you can use API7 Enterprise or API7 Cloud which are powered by APISIX.

Related resources

Recommended content

Community⤵️

🙋 Join the Apache APISIX Community
🐦 Follow us on Twitter
📝 Find us on Slack

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .