Skip to main content

🚀 | Use Custom Handlers For Go

· 6 min read
Melony Qin

Welcome to Day 12 of #30DaysOfServerless!

Today, we have a special set of posts from our Zero To Hero 🚀 initiative, featuring blog posts authored by our Product Engineering teams for #ServerlessSeptember. Posts were originally published on the Apps on Azure blog on Microsoft Tech Community.


What We'll Cover​

  • What are Custom Handlers, and why use them?
  • How Custom Handler Works
  • Message Processing With Azure Custom Handler
  • Azure Portal Monitoring


If you have been working with Azure Functions for a while, you may know Azure Functions is a serverless FaaS (Function as a Service) offered provided by Microsoft Azure, which is built for your key scenarios, including building web APIs, processing file uploads, responding to database changes, processing IoT data streams, managing message queues, and more.

Custom Handlers: What and Why​

Azure functions support multiple programming languages including C#, F#, Java, JavaScript, Python, typescript, and PowerShell. If you want to get extended language support with Azure functions for other languages such as Go, and Rust, that’s where custom handler comes in.

An Azure function custom handler allows the use of any language that supports HTTP primitives and author Azure functions. With custom handlers, you can use triggers and input and output bindings via extension bundles, hence it supports all the triggers and bindings you're used to with Azure functions.

How a Custom Handler Works​

Let’s take a look at custom handlers and how it works.

  • A request is sent to the function host when an event is triggered. It’s up to the function host to issue a request payload to the custom handler, which holds the trigger and inputs binding data as well as other metadata for the function.
  • The custom handler is a local HTTP web server. It executes the function code and returns a response payload to the Functions host.
  • The Functions host passes data from the response to the function's output bindings which will be passed to the downstream stream services for data processing.

Check out this article to know more about Azure functions custom handlers.


Message processing with Custom Handlers​

Message processing is one of the key scenarios that Azure functions are trying to address. In the message-processing scenario, events are often collected in queues. These events can trigger Azure functions to execute a piece of business logic.

You can use the Service Bus trigger to respond to messages from an Azure Service Bus queue - it's then up to the Azure functions custom handlers to take further actions to process the messages. The process is described in the following diagram:

Building Serverless Go Applications with Azure functions custom handlers

In Azure function, the function.json defines the function's trigger, input and output bindings, and other configuration settings. Note that every function can have multiple bindings, but it can only have one trigger. The following is an example of setting up the Service Bus queue trigger in the function.json file :

{
"bindings": [
{
"name": "queueItem",
"type": "serviceBusTrigger",
"direction": "in",
"queueName": "functionqueue",
"connection": "ServiceBusConnection"
}
]
}

You can add a binding definition in the function.json to write the output to a database or other locations of your desire. Supported bindings can be found here.

As we’re programming in Go, so we need to set the value of defaultExecutablePath to handler in the customHandler.description section in the host.json file.

Assume we’re programming in Windows OS, and we have named our go application as server.go, after we executed go build server.go command, it produces an executable called server.exe. So here we set server.exe in the host.json as the following example :

  "customHandler": {
"description": {
"defaultExecutablePath": "./server.exe",
"workingDirectory": "",
"arguments": []
}
}

We’re showcasing a simple Go application here with Azure functions custom handlers where we print out the messages received from the function host. The following is the full code of server.go application :

package main

import (
"encoding/json"
"fmt"
"log"
"net/http"
"os"
)

type InvokeRequest struct {
Data map[string]json.RawMessage
Metadata map[string]interface{}
}

func queueHandler(w http.ResponseWriter, r *http.Request) {
var invokeRequest InvokeRequest

d := json.NewDecoder(r.Body)
d.Decode(&invokeRequest)

var parsedMessage string
json.Unmarshal(invokeRequest.Data["queueItem"], &parsedMessage)

fmt.Println(parsedMessage)
}

func main() {
customHandlerPort, exists := os.LookupEnv("FUNCTIONS_CUSTOMHANDLER_PORT")
if !exists {
customHandlerPort = "8080"
}
mux := http.NewServeMux()
mux.HandleFunc("/MessageProcessorFunction", queueHandler)
fmt.Println("Go server Listening on: ", customHandlerPort)
log.Fatal(http.ListenAndServe(":"+customHandlerPort, mux))

}

Ensure you have Azure functions core tools installed, then we can use func start command to start our function. Then we’ll have have a C#-based Message Sender application on Github to send out 3000 messages to the Azure service bus queue. You’ll see Azure functions instantly start to process the messages and print out the message as the following:

Monitoring Serverless Go Applications with Azure functions custom handlers


Azure portal monitoring​

Let’s go back to Azure portal portal the events see how those messages in Azure Service Bus queue were being processed. There was 3000 messages were queued in the Service Bus queue ( the Blue line stands for incoming Messages ). The outgoing messages (the red line in smaller wave shape ) showing there are progressively being read by Azure functions as the following :

Monitoring Serverless Go Applications with Azure functions custom handlers

Check out this article about monitoring Azure Service bus for further information.

Next steps​

Thanks for following along, we’re looking forward to hearing your feedback. Also, if you discover potential issues, please record them on Azure Functions host GitHub repository or tag us @AzureFunctions on Twitter.

RESOURCES

Start to build your serverless applications with custom handlers, check out the official documentation:

Life is a journey of learning. Let’s stay tuned!