azfunc

package module
v0.15.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 29, 2024 License: MIT Imports: 11 Imported by: 0

README

azfunc

Go Reference

Module to assist with Azure Functions with Custom handlers and Go

The purpose of this module is to provide functions and structures that helps with handling the incoming and outgoing requests to and from the Azure Function host when developing Azure Functions with Custom handlers and Go.

Contents

Why use this module?

After writing several Azure Functions with Custom handlers for Go I came to realize that the process of handling the incoming request payload from the Function host a tedious task (the overall structure and some content being escaped) and I found myself rewriting this request handling time and time again, every time with different ways and end result.

The idea of this module awoke to address this and to create a uniform way to do it across my current and future projects.

Install

Prerequisites

  • Go 1.18
go get github.com/KarlGW/azfunc

Usage

The framework takes care of setting up the server and handlers, and you as a user register functions and bindings. Each function must have a corresponding function.json with binding specifications, in a folder named after the function. For more information about bindings, check out the documentation.

The triggers and bindings registered to the FunctionApp must match with the names of the bindings in this file, the exception being with HTTP triggers and bindings, req and res where this is handled without the names for convenience.

Creating this application structure can be done with ease with the help of the Function Core tools. In addition to scaffolding functions it can be used to run and test your functions locally.

An example on how to create a function with a HTTP trigger and a HTTP output binding (response) is provided further below.

Concepts

When working with the FunctionApp there are some concepts to understand and work with. The FunctionApp represents the entire Function App, and it is to this structure the functions (with their triggers and output bindings) that should be run are registered to. Each function that is registered contains a *azfunc.Context and a trigger.

The triggers is the triggering event and the data it contains, and the context contains output bindings (and writing to them), output error and logging.

Triggers (input bindings)

HTTP trigger

Triggered by an incoming HTTP event. The trigger contains the HTTP data (headers, url, query, params and body).

func(ctx *azfunc.Context, trigger *triggers.HTTP)

Timer trigger

Triggered by a schedule. The trigger contains the timer data (next and last run etc).

func(ctx *azfunc.Context, trigger *triggers.Timer)

Queue trigger

Triggered by a message to an Azure Queue Storage queue.

func(ctx *azfunc.Context, trigger *triggers.Queue)

Service Bus trigger

Triggered by a message to an Azure Service Bus queue or topic subscription.

func(ctx *azfunc.Context, trigger *triggers.ServiceBus)

Event Grid trigger

Triggered by an event to an Azure Event Grid topic subscription.

func(ctx *azfunc.Context, trigger *triggers.EventGrid)

Generic trigger

Generic trigger is a generic trigger can be used for all not yet supported triggers. The data it contains needs to be parsed into a struct matching the expected incoming payload.

func(ctx *azfunc.Context, trigger *triggers.Generic)
Output (output bindings)

HTTP binding

Writes an HTTP response back to the caller (only works together with an HTTP trigger).

Queue binding

Writes a message to a queue in Azure Queue Storage.

Service Bus binding

Writes a message to a queue or topic subscription in Azure Service Bus.

Generic binding

Generic binding is a generic binding that can be used for all not yet supported bindings.

Context

The context is the Function context, named so due to it being called so in the Azure Function implementation of other languages (foremost the old way of handling JavaScript/Node.js functions).

Assuming the *azfunc.Context is bound to the name ctx:

  • ctx.Log():
    • ctx.Log().Info() for info level logs.
    • ctx.Log().Error() for error level logs.
  • ctx.Binding("<binding-name>") - Provides access to the binding by name. If the binding it hasn't been provided together with the function at registration, it will created as a *bindings.Generic (will work as long as a binding with that same name is defined in the functions function.json).
  • ctx.Err() - Get the error set to the context.
  • ctx.SetError(err) - Set an error to the context. This will signal to the underlying host that an error has occured and the execution will count as a failure. Use this followed by a return in the provided function to represent an "unrecoverable" error and exit early.
Error handling

The functions provided to the FunctionApp has no return value, and as such does not return errors. These needs be handled by either setting them to the *azfunc.Context and passed on to be handled by the function executor in the FunctionApp, or handling them in some way within the function code.

As an example: A function is triggered and run, and encounters an error for one of it's calls. This error is deemed to be fatal and the function cannot carry on further. Then setting the error to the context and returning is the preferred way, like so:

func run(ctx *azfunc.Context, trigger *triggers.Queue) {
    if err := someFunc(); err != nil {
        // This error is fatal, and must be signaled to the function host.
        ctx.SetError(err)
        return
    }
}

An example of when an error is not regarded as fatal, but not application breaking (like a malformed HTTP request), it can be handled like so:

func run(ctx *azfunc.Context, trigger *triggers.HTTP) {
    var incoming IncomingRequest
    if err := trigge.Parse(&incoming); err != nil {
        // The incoming request body did not match the expected one,
        // this is equivalent of a HTTP 400.
        ctx.HTTP().WriteHeader(http.StatusBadRequest)
        return
    }
}
HTTP trigger and HTTP output binding

Create hello-http/function.json with a HTTP trigger and HTTP output binding

{
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    },
  ]
}
package main

import (
	"github.com/KarlGW/azfunc"
	"github.com/KarlGW/azfunc/triggers"
)

func main() {
    app := azfunc.NewFunctionApp()

    app.AddFunction("hello-http", azfunc.HTTPTrigger(func(ctx *azfunc.Context, trigger *triggers.HTTP) {
        // Parse the incoming trigger body into the custom type.
        // To get the raw data of the body, use trigger.Data instead.
        var t test
        if err := trigger.Parse(&t); err != nil {
            // Send response back to caller.
            ctx.Output.HTTP().WriteHeader(http.StatusBadRequest)
            return
        }
        // Do something with t.
        // Create the response.
        ctx.Output.HTTP().WriteHeader(http.StatusOK)
        ctx.Output.HTTP().Header().Add("Content-Type", "application/json")
        ctx.Output.HTTP().Write([]byte(`{"message":"received"}`))
    }))

    if err := app.Start(); err != nil {
        // Handle error.
    }
}

type test struct {
    Message string `json:"message"`
}

More examples with different triggers and output can be found here.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNoFunction is returned when no function has been set to the
	// FunctionApp.
	ErrNoFunction = errors.New("at least one function must be set")
)

Functions

This section is empty.

Types

type Context

type Context struct {

	// Output contains bindings.
	Output Output
	// contains filtered or unexported fields
}

Context represents the function context and contains output, bindings, services and clients.

func (*Context) Clients

func (c *Context) Clients() clients

Clients returns the clients set in the Context.

func (Context) Err added in v0.3.0

func (c Context) Err() error

Err returns the error set to the Context.

func (Context) Log added in v0.2.0

func (c Context) Log() logger

Log returns the logger of the Context.

func (*Context) Services

func (c *Context) Services() services

Services returns the services set in the Context.

func (*Context) SetError added in v0.3.0

func (c *Context) SetError(err error)

SetError sets an error to the Context.

func (*Context) SetLogger added in v0.3.0

func (c *Context) SetLogger(l logger)

SetLogger sets a logger to the Context. Should not be used in most use-cases due to it being set by the FunctionApp.

type EventGridTriggerFunc added in v0.14.0

type EventGridTriggerFunc func(ctx *Context, trigger *triggers.EventGrid)

EventGridTriggerFunc represents an Event Grid trigger function to be executed by the function app.

type FunctionApp

type FunctionApp struct {
	// contains filtered or unexported fields
}

FunctionApp represents a Function App with its configuration and functions.

func NewFunctionApp

func NewFunctionApp(options ...FunctionAppOption) *FunctionApp

NewFunction app creates and configures a FunctionApp.

func (*FunctionApp) AddFunction

func (a *FunctionApp) AddFunction(name string, options ...FunctionOption)

AddFunction adds a function to the FunctionApp.

func (FunctionApp) Start

func (a FunctionApp) Start() error

Start the FunctionApp.

type FunctionAppOption

type FunctionAppOption func(*FunctionApp)

FunctionAppOption is a function that sets options to a FunctionApp.

func WithClient

func WithClient(name string, client any) FunctionAppOption

WithClient sets the provided client to the FunctionApp. Can be called multiple times. If a client with the same name has been set it will be overwritten.

func WithLogger

func WithLogger(log logger) FunctionAppOption

WithLogger sets the provided logger to the FunctionApp. The logger must satisfy the logger interface.

func WithService

func WithService(name string, service any) FunctionAppOption

WithService sets the provided service to the FunctionApp. Can be called multiple times. If a service with the same name has been set it will be overwritten.

type FunctionOption

type FunctionOption func(f *function)

FunctionOption sets options to the function.

func Binding

func Binding(binding bindable) FunctionOption

Binding sets the provided binding to the function.

func EventGridTrigger added in v0.14.0

func EventGridTrigger(name string, fn EventGridTriggerFunc, options ...triggers.EventGridOption) FunctionOption

EventGridTrigger takes the provided name and function and sets it as the function to be run by the trigger.

func GenericTrigger added in v0.15.0

func GenericTrigger(name string, fn GenericTriggerFunc, options ...triggers.GenericOption) FunctionOption

GenericTrigger takes the provided name and function and sets it as the function to be run by the trigger.

func HTTPTrigger

func HTTPTrigger(fn HTTPTriggerFunc, options ...triggers.HTTPOption) FunctionOption

HTTPTrigger takes the provided function and sets it as the function to be run by the trigger.

func QueueTrigger

func QueueTrigger(name string, fn QueueTriggerFunc, options ...triggers.QueueOption) FunctionOption

QueueTrigger takes the provided name and function and sets it as the function to be run by the trigger.

func ServiceBusTrigger added in v0.7.0

func ServiceBusTrigger(name string, fn ServiceBusTriggerFunc, options ...triggers.ServiceBusOption) FunctionOption

ServiceBusTrigger takes the provided name and function and sets it as the function to be run by the trigger.

func TimerTrigger

func TimerTrigger(fn TimerTriggerFunc, options ...triggers.TimerOption) FunctionOption

TimerTrigger takes the provided function and sets it as the function to be run by the trigger.

type GenericTriggerFunc added in v0.15.0

type GenericTriggerFunc func(ctx *Context, trigger *triggers.Generic)

GenericTriggerFunc represents a generic function to be executed by the function app.

type HTTPTriggerFunc

type HTTPTriggerFunc func(ctx *Context, trigger *triggers.HTTP)

HTTPTriggerFunc represents an HTTP trigger function to be executed by the function app.

type Output added in v0.11.0

type Output struct {
	Outputs     map[string]bindable
	ReturnValue any

	Logs []string
	// contains filtered or unexported fields
}

Output represents an outgoing response to the Functuon Host.

func NewOutput added in v0.11.0

func NewOutput(options ...OutputOption) Output

NewOutput creates a new Output containing binding to be used for creating the response back to the Function host.

func (*Output) AddBindings added in v0.11.0

func (o *Output) AddBindings(bindables ...bindable)

AddBindings one or more bindings to Output.

func (Output) Binding added in v0.11.0

func (o Output) Binding(name string) bindable

Binding returns the binding with the provided name, if no binding with that name exists, return a new generic binding with the provided name.

func (*Output) HTTP added in v0.11.0

func (o *Output) HTTP() *bindings.HTTP

HTTP returns the HTTP binding of output if any is set. If not set it will create, set and return it.

func (Output) JSON added in v0.11.0

func (o Output) JSON() []byte

JSON returns the JSON encoding of Output.

func (*Output) Log added in v0.11.0

func (o *Output) Log(msg string)

Log adds a message to the Logs of Output.

func (Output) MarshalJSON added in v0.11.0

func (o Output) MarshalJSON() ([]byte, error)

MarshalJSON implements custom marshaling to produce the required JSON structure as expected by the function host.

func (*Output) SetReturnValue added in v0.11.0

func (o *Output) SetReturnValue(v any)

SetReturnValue sets ReturnValue of Output.

type OutputOption added in v0.11.0

type OutputOption func(o *OutputOptions)

Output option is a function that sets OutputOptions.

func WithBindings added in v0.11.0

func WithBindings(bindables ...bindable) OutputOption

WithBindings add one or more bindings to OutputOptions

type OutputOptions added in v0.11.0

type OutputOptions struct {
	ReturnValue any

	Bindings []bindable
	Logs     []string
	// contains filtered or unexported fields
}

OutputOptions contains options for creating a new Output.

type QueueTriggerFunc added in v0.7.0

type QueueTriggerFunc func(ctx *Context, trigger *triggers.Queue)

QueueTriggerFunc represents a Queue Storage trigger function to be exexuted by the function app.

type ServiceBusTriggerFunc added in v0.7.0

type ServiceBusTriggerFunc func(ctx *Context, trigger *triggers.ServiceBus)

ServiceBusTriggerFunc represents a Service Bus trigger function to be exexuted by the function app.

type TimerTriggerFunc added in v0.2.0

type TimerTriggerFunc func(ctx *Context, trigger *triggers.Timer)

TimerTriggerFunc represents a Timer trigger function tp be executed by the function app.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL