Language runtimes
Go
Write a Coderunner Function, Job or Schedule in Go.
Use this reference for Functions, Jobs and Schedules written in Go. For a container with your own web server, see Services.
Project files
my-function/
├── handler.go
├── go.mod
└── helpers.go (optional)Zip these at the root of the archive, not inside a folder. Every .go file uses package main, and helper files sit next to handler.go rather than in subfolders.
module app
go 1.24The handler
Export a function named Handler that returns a HandlerResult:
package main
type HandlerResult struct {
StatusCode int `json:"-"`
Headers map[string]string `json:"headers"`
Body map[string]interface{} `json:"body"`
}
func Handler(context map[string]interface{}, payload map[string]interface{}) HandlerResult {
// your code
}payloadis the JSON input: the request body for a Function, the run's input for a Job.contextis reserved for information from the runtime. Don't rely on its contents yet.
You don't need http.ListenAndServe or any routing.
Function example
package main
import (
"fmt"
"net/http"
)
type HandlerResult struct {
StatusCode int `json:"-"`
Headers map[string]string `json:"headers"`
Body map[string]interface{} `json:"body"`
}
func Handler(context map[string]interface{}, payload map[string]interface{}) HandlerResult {
headers := map[string]string{"content-type": "application/json"}
name, _ := payload["name"].(string)
if name == "" {
return HandlerResult{
StatusCode: http.StatusBadRequest,
Headers: headers,
Body: map[string]interface{}{"error": "name is required"},
}
}
return HandlerResult{
StatusCode: http.StatusOK,
Headers: headers,
Body: map[string]interface{}{"greeting": fmt.Sprintf("Hello, %s", name)},
}
}Return an error result rather than panicking.
Job and Schedule example
func Handler(context map[string]interface{}, payload map[string]interface{}) HandlerResult {
log.Println("Import started")
count, err := importCustomers(payload)
if err != nil {
log.Println("Import failed:", err)
return HandlerResult{StatusCode: http.StatusInternalServerError, Body: map[string]interface{}{"error": "import failed"}}
}
log.Printf("Imported %d customers\n", count)
return HandlerResult{StatusCode: http.StatusOK, Body: map[string]interface{}{"imported": count}}
}Error handling is up to you; see Jobs.
Settings, secrets and logs
- Read settings with
os.Getenv("NAME"). See Configuration and secrets. - Read secrets from the Secrets API at runtime, never from your ZIP; see Configuration and secrets.
- Output from
fmtandloggoes to the Process Log.
Deploy
gf deploy --name my-function --runtime go --workload-type functionOr create the Coderunner in the Client Portal and upload the ZIP; see Functions.