# Functions Go Runtime Functions are blocks of code that run on demand without the need to manage any infrastructure. Develop on your local machine, test your code from the command line (using `doctl`), then deploy to a production namespace or App Platform — no servers required. Functions supports Go 1.17 (`go:1.17`), Go 1.20 (`go:1.20`), Go 1.24 (`go:1.24`), and Go 1.25 (`go:1.25`). Specify the desired runtime and version with the [`runtime` key in your `project.yml` file](https://docs.digitalocean.com/products/functions/reference/project-configuration/index.html.md#runtime), or choose one from the **Runtime** dropdown menu when creating a function in the control panel. The Functions Go runtime passes [two parameters](#parameters) to your handler function, and expects either no return value or a [properly formatted response](#returns) type. ## A Go Hello World Function Here is a Go function that responds with a greeting and some information about the function version: ```go package main import ( "context" ) type Event struct { Name string `json:"name"` } type Response struct { Body string `json:"body"` } func Main(ctx context.Context, event Event) Response { if event.Name == "" { event.Name = "stranger" } version := ctx.Value("function_version").(string) return Response { Body: "Hello " + event.Name + "! This is function version " + version, } } ``` The runtime expects a function called `Main` to act as the *entry point* or the *handler*. This handler function is the only function where the runtime passes in data and receive responses. You can set a different function name as the handler using the [`main` key in `project.yml`](https://docs.digitalocean.com/products/functions/reference/project-configuration/index.html.md#main). The `Main` function above takes two parameters: a `ctx` of the built-in type `context.Context`, and `event` with a custom `Event` type. It returns a response where the `Body` is a greeting to the user-provided `Name` (if any) in the event, and the function version provided in then context. After [adding this function to your namespace](https://docs.digitalocean.com/products/functions/how-to/create-functions/index.html.md), you can call this function by pasting its URL into your browser and adding a `name` field in a query string at the end: ``` https://?name=Sammy ``` **Note**: You can get the URL for your function from the control panel interface, or by running the following command on the command line: ```shell doctl serverless function get --url ``` Or use `curl` to send the input as form data in the body of the request: ```sh curl -d 'name=Sammy' ``` Either way, the function returns the response body: ``` Hello Sammy! This is function version 0.0.2 ``` ## Parameters The handler function is passed two parameters. The first represents the function’s execution context, and the second is the event, often representing an HTTP request. **Note**: Information about function parameters that is not language-specific can be found in the [Parameters and Responses](https://docs.digitalocean.com/products/functions/reference/parameters-responses/index.html.md) reference documentation. The first parameter, [`context`](#context-parameter), is data about the function’s execution environment, such as memory allocations and the time remaining before a timeout. The second parameter, [`event`](#event-parameter), is the input event that initiated the function. When this is an HTTP event, it’s called a *web event*. Both parameters are optional and you may ignore them if your function doesn’t require the information they provide. The parameter list for your handler function should look like one of the following: - `(context.Context, yourEventType)`: Accesses both parameters, where `yourEventType` is any type that can be unmarshalled using the `encoding/json` package. - `(context.Context)`: Accesses only the context. - `(yourEventType)`: Accesses only the event, where `yourEventType` is any type that can be unmarshalled using the `encoding/json` package. - `()`: Accesses neither. ### Event Parameter The event parameter is unmarshalled from a JSON object. It is structured like the following example JSON: ```json { "http": { "headers": { "accept": "*/*", "accept-encoding": "gzip", "user-agent": "curl/7.85.0", "x-forwarded-for": "203.0.113.11", "x-forwarded-proto": "https", "x-request-id": "5df6f6b0d00b58217439c8376fcae23a" }, "method": "POST", "path": "" }, "shark": "hammerhead" } ``` This example event has had a `shark: hammerhead` input passed to it. This has been parsed and added as a top-level key to the dictionary. More details on the information contained in the `event` parameter is available under the [Event Parameter section](https://docs.digitalocean.com/products/functions/reference/parameters-responses/index.html.md#event-parameter) of the Parameters and Responses reference documentation. ### Context Parameter The context parameter is [the `context.Context` type built into Go](https://pkg.go.dev/context#Context). The context has deadline and typed values that can be retrieved using the `Value` method. See [the official `context.Context` docs](https://pkg.go.dev/context#Context) for more information on using this type. The context parameter contains additional values. Here they are represented as keys of a JSON object with sample values. All of the context values are strings: ```json { "activation_id": "5f56b7e9fbd84b2f96b7e9fbd83b2f2e", "api_host": "https://faas-nyc1-2ef2e6cc.doserverless.co", "api_key": "", "function_name": "/fn-52ad03a2-8660-4f7c-55a5-81aa8bbe73b1/example", "function_version": "0.0.10", "namespace": "fn-52ad03a2-8660-4f7c-55a5-81aa8bbe73b1", "request_id": "452164dfeced0a7ad91ee675609024e7" } ``` The context data doesn’t contain the deadline value. This is because Go contexts already have a concept of deadlines, so the runtime uses that. To get the deadline of the context, use the `Deadline` method: ```go deadline, _ := ctx.Deadline() ``` To retrieve values from the context parameter, use the `Value` method: ```go id := ctx.Value("activation_id").(string) ``` More details on the information contained in the `context` parameter is available under the [Context Parameter section](https://docs.digitalocean.com/products/functions/reference/parameters-responses/index.html.md#context-parameter) of the Parameters and Responses reference documentation. ## Returns To send a response, your function must return a properly formatted response dictionary. The following return types can be used in Go functions: - Use `yourEventType` to return a strongly typed result, where `yourEventType` is any type that can be unmarshalled using the `encoding/json` package. Make sure your struct has a field that can be rendered as a JSON `body` property to return data to the client. - Use `map[string]interface` to return any key-value pairs you want. Make sure that one of the keys is `body` to return data to the client. - Return no value if you do not need to return data to the client. More details on the response can be found in the [Returns section](https://docs.digitalocean.com/products/functions/reference/parameters-responses/index.html.md#returns) of the Parameters and Responses reference documentation. ## Example Functions ### Return JSON If the `body` is a type that can be serializable as JSON by the `encoding/json` package, it is automatically serialized as JSON and returned with a `Content-Type: application/json` header. ```go package main type Shark struct { Type string `json:"type"` } type Response struct { Body []Shark `json:"body"` } func Main() Response { return Response{ Body: []Shark{ { Type: "hammerhead", }, { Type: "mako", }, }, } } ``` ### Return an Image To return an image or other media type, set the correct `Content-Type` header and return a base64-encoded `body`: ```go package main type ResponseHeaders struct { ContentType string `json:"Content-Type"` } type Response struct { Body string `json:"body"` StatusCode string `json:"statusCode"` Headers ResponseHeaders `json:"headers"` } func Main() Response { // example 1x1 GIF gif := "R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" return Response{ Body: gif, StatusCode: "200", Headers: ResponseHeaders{ ContentType: "image/gif", }, } } ``` ### Return an HTTP Redirect A `302` status code and `location` header redirects an HTTP client to a new URL: ```go package main type ResponseHeaders struct { Location string `json:"location"` } type Response struct { StatusCode string `json:"statusCode"` Headers ResponseHeaders `json:"headers"` } func Main() Response { return Response{ StatusCode: "302", Headers: ResponseHeaders{ Location: "https://example.com", }, } } ``` ### Return HTML and Set a Cookie Set cookies with the `Set-Cookie` header, and use the `Content-Type: 'text/html'` header to return HTML content: ```go package main type ResponseHeaders struct { SetCookie string `json:"Set-Cookie"` ContentType string `json:"Content-Type"` } type Response struct { Body string `json:"body"` StatusCode string `json:"statusCode"` Headers ResponseHeaders `json:"headers"` } func Main() Response { return Response{ Body: "

Hello, World!

", StatusCode: "200", Headers: ResponseHeaders{ SetCookie: "UserID=Sammy; Max-Age=3600; Version=", ContentType: "text/html", }, } } ``` ### More Example Functions Some more in-depth example Go functions are available on GitHub: [Go Hello World](https://github.com/digitalocean/sample-functions-golang-helloworld) [Go Random Number](https://github.com/digitalocean/sample-functions-golang-random) [Go Presigned URL](https://github.com/digitalocean/sample-functions-golang-presigned-url) [Go MySQL](https://github.com/digitalocean/sample-functions-mysql) [Go Slack Bot](https://github.com/digitalocean/sample-functions-golang-slackbot) ## Log to the Console Any text output to `stdout` and `stderr` is logged and can be accessed through [the `doctl` command line tool](https://docs.digitalocean.com/reference/doctl/index.html.md). Log to `stdout` by using `fmt.Print`, `fmt.Println`, or other similar methods. Make sure to include a newline at the end of the message: ```go fmt.Print("this text is logged\n") ``` Use `doctl serverless activations logs --follow` to follow logs for all functions in the current namespace, or specify a single function with the `--function` flag. See the [`doctl serverless activations logs` reference](https://docs.digitalocean.com/reference/doctl/reference/serverless/activations/logs/index.html.md) for more information, or add the `--help` flag to the command for help output. ## Use Modules and Dependencies To use third-party Go modules, add a `go.mod` and `go.sum` file to the remote build process (Go functions are always built remotely during deploys). First, navigate to the directory containing your function code. Initialize your Go module if necessary (if you already have a `go.mod` file, skip this): ```go go mod init example ``` Add your third-party module, in this case the `gosimple/slug` module: ```go go get github.com/gosimple/slug ``` This creates the entries needed in `go.mod` and `go.sum`. The build process uses these files to download your third-party modules and build your function. If you require different build steps you should create a `build.sh` file in the function directory. Read the [Build Process reference](https://docs.digitalocean.com/products/functions/reference/build-process/index.html.md) for more details on the build process and build scripts. ## Include Files in Built Function To include arbitrary files with your deployed function (for example, config files and templates), you must use Go’s [embed package](https://pkg.go.dev/embed). The files to be embedded must be placed in the same directory as the function source code files. Here is an example function that embeds text content from a file: Directory structure: ``` . ├── packages │ └── │ └── │ ├── main.go │ └── to_be_included.txt └── project.yml ``` `main.go` ```go package main import ( _ "embed" "fmt" ) //go:embed to_be_included.txt var s string type Response struct { Body string `json:"body"` } func Main() Response { return Response{ Body: fmt.Sprintf("File contents: %q\n", s), } } ``` `to_be_included.txt` ```text Hello, World! ``` When invoked, the response is: ``` File contents: "Hello, World!" ```