

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

# Definieren des Lambda-Funktions-Handlers in Go
<a name="golang-handler"></a>

Der Lambda-Funktions*handler* ist die Methode in Ihrem Funktionscode, die Ereignisse verarbeitet. Wenn Ihre Funktion aufgerufen wird, führt Lambda die Handler-Methode aus. Ihre Funktion wird so lange ausgeführt, bis der Handler eine Antwort zurückgibt, beendet wird oder ein Timeout auftritt.

Auf dieser Seite wird beschrieben, wie Sie mit Lambda-Funktionshandlern in Go arbeiten, einschließlich der Projekteinrichtung, Benennungskonventionen und Best Practices. Diese Seite enthält auch ein Beispiel für eine Go-Lambda-Funktion, die Informationen über einen Auftrag aufnimmt, eine Textdatei als Quittung erstellt und diese Datei in einem Bucket von Amazon Simple Storage Service (Amazon S3) platziert. Informationen darüber, wie Sie Ihre Funktion nach dem Schreiben einsetzen können, finden Sie unter [Bereitstellen von Lambda-Go-Funktionen mit ZIP-Dateiarchiven](golang-package.md) oder [Bereitstellen von Go-Lambda-Funktionen mit Container-Images](go-image.md).

**Topics**
+ [Einrichten Ihres Go-Handler-Projekts](#golang-handler-setup)
+ [Beispiel für Go Lambda-Funktionscode](#golang-example-code)
+ [Namenskonventionen für Handler](#golang-handler-naming)
+ [Definieren Sie das Eingabeereignisobjekt und greifen Sie darauf zu](#golang-example-input)
+ [Zugreifen auf und Verwenden des Lambda-Kontextobjekts](#golang-example-context)
+ [Gültige Handler-Signaturen für Go-Handler](#golang-handler-signatures)
+ [Verwenden Sie die AWS SDK für Go v2 in Ihrem Handler](#golang-example-sdk-usage)
+ [Zugriff auf Umgebungsvariablen](#golang-example-envvars)
+ [Verwenden des globalen Zustands](#golang-handler-state)
+ [Bewährte Codemethoden für Go-Lambda-Funktionen](#go-best-practices)

## Einrichten Ihres Go-Handler-Projekts
<a name="golang-handler-setup"></a>

Eine Lambda-Funktion in [Go](https://golang.org/) wird als ausführbare Go-Datei erstellt. Sie können ein Go-Lambda-Funktionsprojekt auf die gleiche Weise initialisieren wie jedes andere Go-Projekt, indem Sie den folgenden `go mod init`-Befehl verwenden:

```
go mod init example-go
```

Hier ist `example-go` der Name des Moduls. Sie können dies durch alles ersetzen. Dieser Befehl initialisiert Ihr Projekt und erzeugt die `go.mod`-Datei, in der die Abhängigkeiten Ihres Projekts aufgelistet sind.

Verwenden Sie den Befehl `go get`, um externe Abhängigkeiten zu Ihrem Projekt hinzuzufügen. Für alle Lambda-Funktionen in Go müssen Sie zum Beispiel das Paket [github.com/aws/aws-lambda-go/lambda](https://github.com/aws/aws-lambda-go/tree/master/lambda) einbinden, das das Lambda-Programmiermodell für Go implementiert. Binden Sie dieses Paket mit dem folgenden `go get`-Befehl ein:

```
go get github.com/aws/aws-lambda-go
```

Ihr Funktionscode sollte sich in einer Go-Datei befinden. Im folgenden Beispiel benennen wir diese Datei `main.go`. In dieser Datei implementieren Sie Ihre Kernfunktionslogik in einer Handler-Methode sowie in einer `main()`-Funktion, die diesen Handler aufruft.

## Beispiel für Go Lambda-Funktionscode
<a name="golang-example-code"></a>

Das folgende Beispiel für einen Go-Lambda-Funktionscode nimmt Informationen über eine Bestellung auf, erstellt eine Textdateiquittung und platziert diese Datei in einem Amazon-S3-Bucket.

**Example `main.go`-Lambda-Funktion**  

```
package main

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"os"
	"strings"

	"github.com/aws/aws-lambda-go/lambda"
	"github.com/aws/aws-sdk-go-v2/config"
	"github.com/aws/aws-sdk-go-v2/service/s3"
)

type Order struct {
	OrderID string  `json:"order_id"`
	Amount  float64 `json:"amount"`
	Item    string  `json:"item"`
}

var (
	s3Client *s3.Client
)

func init() {
	// Initialize the S3 client outside of the handler, during the init phase
	cfg, err := config.LoadDefaultConfig(context.TODO())
	if err != nil {
		log.Fatalf("unable to load SDK config, %v", err)
	}

	s3Client = s3.NewFromConfig(cfg)
}

func uploadReceiptToS3(ctx context.Context, bucketName, key, receiptContent string) error {
	_, err := s3Client.PutObject(ctx, &s3.PutObjectInput{
		Bucket: &bucketName,
		Key:    &key,
		Body:   strings.NewReader(receiptContent),
	})
	if err != nil {
		log.Printf("Failed to upload receipt to S3: %v", err)
		return err
	}
	return nil
}

func handleRequest(ctx context.Context, event json.RawMessage) error {
	// Parse the input event
	var order Order
	if err := json.Unmarshal(event, &order); err != nil {
		log.Printf("Failed to unmarshal event: %v", err)
		return err
	}

	// Access environment variables
	bucketName := os.Getenv("RECEIPT_BUCKET")
	if bucketName == "" {
		log.Printf("RECEIPT_BUCKET environment variable is not set")
		return fmt.Errorf("missing required environment variable RECEIPT_BUCKET")
	}

	// Create the receipt content and key destination
	receiptContent := fmt.Sprintf("OrderID: %s\nAmount: $%.2f\nItem: %s",
		order.OrderID, order.Amount, order.Item)
	key := "receipts/" + order.OrderID + ".txt"

	// Upload the receipt to S3 using the helper method
	if err := uploadReceiptToS3(ctx, bucketName, key, receiptContent); err != nil {
		return err
	}

	log.Printf("Successfully processed order %s and stored receipt in S3 bucket %s", order.OrderID, bucketName)
	return nil
}

func main() {
	lambda.Start(handleRequest)
}
```

Diese `main.go`-Datei enthält die folgenden Abschnitte des Codes:
+ `package main`: In Go muss das Paket, das Ihre `func main()`-Funktion enthält, immer `main` heißen.
+ `import`-Block: Verwenden Sie diesen Block, um Bibliotheken einzubinden, die Ihre Lambda-Funktion benötigt.
+ `type Order struct {}`-Block: Definieren Sie die Form des erwarteten Eingabeereignisses in dieser Go-Struktur.
+ `var ()`-Block: Verwenden Sie diesen Block, um alle globalen Variablen zu definieren, die Sie in Ihrer Lambda-Funktion verwenden werden.
+ `func init() {}`: Fügen Sie in diese `init()`-Methode beliebigen Code ein, den Lambda während der [Initialisierungsphase](lambda-runtime-environment.md#runtimes-lifecycle-ib) ausführen soll.
+ `func uploadReceiptToS3(...) {}`: Dies ist eine Hilfsmethode, auf die von der `handleRequest`-Haupthandler-Methode verwiesen wird.
+ `func handleRequest(ctx context.Context, event json.RawMessage) error {}`: Dies ist die **Haupthandler-Methode**, die Ihre Hauptanwendungslogik enthält.
+ `func main() {}`: Dies ist ein erforderlicher Einstiegspunkt für Ihren Lambda-Handler. Das Argument für die `lambda.Start()`-Methode ist Ihre Haupthandler-Methode.

Damit diese Funktion ordnungsgemäß funktioniert, muss ihre [Ausführungsrolle](lambda-intro-execution-role.md) die `s3:PutObject`-Aktion zulassen. Stellen Sie außerdem sicher, dass Sie die `RECEIPT_BUCKET`-Umgebungsvariable definieren. Nach einem erfolgreichen Aufruf sollte der Amazon-S3-Bucket eine Empfangsdatei enthalten.

## Namenskonventionen für Handler
<a name="golang-handler-naming"></a>

Für Lambda-Funktionen in Go können Sie einen beliebigen Namen für den Handler verwenden. In diesem Beispiel lautet der Name der Handler-Methode `handleRequest`. Sie können die Umgebungsvariable `_HANDLER` verwenden, um in Ihrem Code auf den Handler-Wert zu verweisen.

Bei Go-Funktionen, die mit einem [.zip-Bereitstellungspaket](golang-package.md) bereitgestellt werden, muss die ausführbare Datei, die Ihren Funktionscode enthält, den Namen `bootstrap` tragen. Darüber hinaus muss sich die `bootstrap`-Datei im Stammverzeichnis der .zip-Datei befinden. Für Go-Funktionen, die über ein [Container-Image](go-image.md#go-image-provided) bereitgestellt werden, können Sie einen beliebigen Namen für die ausführbare Datei verwenden.

## Definieren Sie das Eingabeereignisobjekt und greifen Sie darauf zu
<a name="golang-example-input"></a>

JSON ist das gebräuchlichste und standardmäßigste Eingabeformat für Lambda-Funktionen. In diesem Beispiel erwartet die Funktion eine Eingabe ähnlich der folgenden:

```
{
    "order_id": "12345",
    "amount": 199.99,
    "item": "Wireless Headphones"
}
```

Wenn Sie mit Lambda-Funktionen in Go arbeiten, können Sie die Form des erwarteten Eingabeereignisses als Go-Struktur definieren. In diesem Beispiel definieren wir eine Struktur, die einen `Order` darstellt:

```
type Order struct {
    OrderID string  `json:"order_id"`
    Amount  float64 `json:"amount"`
    Item    string  `json:"item"`
}
```

Diese Struktur entspricht der erwarteten Eingabeform. Nachdem Sie Ihre Struktur definiert haben, können Sie eine Handler-Signatur schreiben, die einen generischen JSON-Typ verwendet, der mit der [encoding/json-Standardbibliothek](https://pkg.go.dev/encoding/json) kompatibel ist. Sie können es dann mit der Funktion [func Unmarshal](https://golang.org/pkg/encoding/json/#Unmarshal) in Ihre Struktur deserialisieren. Dies wird in den ersten Zeilen des Handlers veranschaulicht:

```
func handleRequest(ctx context.Context, event json.RawMessage) error {
    // Parse the input event
    var order Order
    if err := json.Unmarshal(event, &order); err != nil {
        log.Printf("Failed to unmarshal event: %v", err)
        return err
    ...
}
```

Nach dieser Deserialisierung können Sie auf die Felder der `order`-Variablen zugreifen. Zum Beispiel holt `order.OrderID` den Wert von `"order_id"` aus der ursprünglichen Eingabe.

**Anmerkung**  
Das `encoding/json`-Paket kann nur auf exportierte Felder zugreifen. Um exportiert werden, müssen Feldnamen in der Ereignisstruktur großgeschrieben werden.

## Zugreifen auf und Verwenden des Lambda-Kontextobjekts
<a name="golang-example-context"></a>

Das Lambda-[Kontextobjekt](golang-context.md) enthält Informationen über Aufruf, Funktion und Ausführungsumgebung. In diesem Beispiel haben wir diese Variable wie `ctx` in der Handler-Signatur deklariert:

```
func handleRequest(ctx context.Context, event json.RawMessage) error {
    ...
}
```

Die `ctx context.Context`-Eingabe ist ein optionales Argument in Ihrem Funktionshandler. Weitere Informationen zu akzeptierten Handler-Signaturen finden Sie unter [Gültige Handler-Signaturen für Go-Handler](#golang-handler-signatures).

Wenn Sie mit dem AWS-SDK andere Dienste aufrufen, wird das Kontextobjekt in einigen wichtigen Bereichen benötigt. Um beispielsweise Ihre SDK-Clients ordnungsgemäß zu initialisieren, können Sie die richtige AWS-SDK-Konfiguration mithilfe des Kontextobjekts wie folgt laden:

```
// Load AWS SDK configuration using the default credential provider chain
    cfg, err := config.LoadDefaultConfig(ctx)
```

SDK-Aufrufe selbst benötigen möglicherweise das Kontextobjekt als Eingabe. Der Aufruf von `s3Client.PutObject` akzeptiert beispielsweise das Kontextobjekt als erstes Argument:

```
// Upload the receipt to S3
    _, err = s3Client.PutObject(ctx, &s3.PutObjectInput{
        ...
    })
```

Außerhalb von AWS-SDK-Anfragen können Sie das Kontextobjekt auch für die Funktionsüberwachung verwenden. Weitere Informationen über das Kontextobjekt finden Sie unter [Verwenden des Lambda-Kontextobjekts zum Abrufen von Go-Funktionsinformationen](golang-context.md).

## Gültige Handler-Signaturen für Go-Handler
<a name="golang-handler-signatures"></a>

Sie haben bei der Erstellung eines Lambda-Funktions-Handlers in Go mehrere Möglichkeiten. Allerdings müssen die folgenden Regeln beachten:
+ Der Handler muss eine Funktion sein.
+ Der Handler kann zwischen 0 und 2 Argumente aufnehmen. Bei zwei Argumenten muss das erste Argument implementiere `context.Context`.
+ Der Handler kann zwischen 0 und 2 Argumente zurückgeben. Bei einem einzigen Rückgabewert muss er implementiere `error`. Bei zwei Rückgabewerten muss der zweite Wert implementiere `error`.

Im Folgenden werden gültige Handler-Signaturen aufgeführt. `TIn` und `TOut` stellen Typen dar, die mit der Standardbibliothek *encoding/json* kompatibel sind. Weitere Informationen zur Deserialisierung dieser Typen finden Sie unter [func Unmarshal](https://golang.org/pkg/encoding/json/#Unmarshal).
+ 

  ```
  func ()
  ```
+ 

  ```
  func () error
  ```
+ 

  ```
  func () (TOut, error)
  ```
+ 

  ```
  func (TIn) error
  ```
+ 

  ```
  func (TIn) (TOut, error)
  ```
+ 

  ```
  func (context.Context) error
  ```
+ 

  ```
  func (context.Context) (TOut, error)
  ```
+ 

  ```
  func (context.Context, TIn) error
  ```
+ 

  ```
  func (context.Context, TIn) (TOut, error)
  ```

## Verwenden Sie die AWS SDK für Go v2 in Ihrem Handler
<a name="golang-example-sdk-usage"></a>

Oft verwenden Sie Lambda-Funktionen, um mit anderen AWS-Ressourcen zu interagieren oder diese zu aktualisieren. Die einfachste Art, eine Schnittstelle zu diesen Ressourcen herzustellen, ist die Verwendung von [AWS SDK für Go v2](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2).

**Anmerkung**  
AWS SDK für Go (v1) befindet sich im Wartungsmodus und der Support wird am 31. Juli 2025 eingestellt. Wir empfehlen, dass Sie in Zukunft nur noch AWS SDK für Go v2 verwenden.

Um Ihrer Funktion SDK-Abhängigkeiten hinzuzufügen, verwenden Sie den `go get`-Befehl für die spezifischen SDK-Clients, die Sie benötigen. Im Beispielcode zuvor haben wir die `config`-Bibliothek und die `s3`-Bibliothek verwendet. Fügen Sie diese Abhängigkeiten hinzu, indem Sie die folgenden Befehle in dem Verzeichnis ausführen, das Ihre `go.mod`- und `main.go `-Dateien enthält:

```
go get github.com/aws/aws-sdk-go-v2/config
go get github.com/aws/aws-sdk-go-v2/service/s3
```

Importieren Sie dann die Abhängigkeiten entsprechend in den Importblock Ihrer Funktion:

```
import (
    ...
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
)
```

Wenn Sie das SDK in Ihrem Handler verwenden, konfigurieren Sie Ihre Clients mit den richtigen Einstellungen. Der einfachste Weg, dies zu tun, besteht darin, die [standardmäßige Anbieterkette für Anmeldeinformationen](https://docs.aws.amazon.com/sdkref/latest/guide/standardized-credentials.html#credentialProviderChain) zu verwenden. Dieses Beispiel zeigt eine Möglichkeit, diese Konfiguration zu laden:

```
// Load AWS SDK configuration using the default credential provider chain
    cfg, err := config.LoadDefaultConfig(ctx)
    if err != nil {
        log.Printf("Failed to load AWS SDK config: %v", err)
        return err
    }
```

Nachdem Sie diese Konfiguration in die `cfg`-Variable geladen haben, können Sie diese Variable an Client-Instanziierungen übergeben. Der Beispielcode instanziiert einen Amazon-S3-Client wie folgt:

```
// Create an S3 client
    s3Client := s3.NewFromConfig(cfg)
```

In diesem Beispiel haben wir unseren Amazon-S3-Client in der `init()`-Funktion initialisiert, um zu vermeiden, dass wir ihn bei jedem Aufruf unserer Funktion initialisieren müssen. Das Problem ist, dass Lambda in der `init()`-Funktion keinen Zugriff auf das Kontextobjekt hat. Als Abhilfe können Sie in der Initialisierungsphase einen Platzhalter wie `context.TODO()` übergeben. Wenn Sie später über den Client einen Anruf tätigen, übergeben Sie das vollständige Kontextobjekt. Diese Abhilfemaßnahme wird auch in [Verwendung des Kontexts bei Initialisierungen und Aufrufen von AWS-SDK-Clients](golang-context.md#golang-context-sdk) beschrieben.

Nachdem Sie Ihren SDK-Client konfiguriert und initialisiert haben, können Sie ihn für die Interaktion mit anderen AWS-Diensten verwenden. Der Beispielcode ruft die Amazon S3 `PutObject`-API wie folgt auf:

```
_, err = s3Client.PutObject(ctx, &s3.PutObjectInput{
    Bucket: &bucketName,
    Key:    &key,
    Body:   strings.NewReader(receiptContent),
})
```

## Zugriff auf Umgebungsvariablen
<a name="golang-example-envvars"></a>

In Ihrem Handler-Code können Sie mithilfe der `os.Getenv()`-Methode auf beliebige [Umgebungsvariablen](configuration-envvars.md) verweisen. In diesem Beispiel verweisen wir mit der folgenden Codezeile auf die definierte `RECEIPT_BUCKET`-Umgebungsvariable:

```
// Access environment variables
    bucketName := os.Getenv("RECEIPT_BUCKET")
    if bucketName == "" {
        log.Printf("RECEIPT_BUCKET environment variable is not set")
        return fmt.Errorf("missing required environment variable RECEIPT_BUCKET")
    }
```

## Verwenden des globalen Zustands
<a name="golang-handler-state"></a>

Um zu vermeiden, dass bei jedem Funktionsaufruf neue Ressourcen erstellt werden, können Sie globale Variablen außerhalb des Handler-Codes Ihrer Lambda-Funktion deklarieren und ändern. Sie definieren diese globalen Variablen in einem `var`-Block oder einer Anweisung. Darüber hinaus deklariert Ihr Handler möglicherweise eine `init()`-Funktion, die während der [Initialisierungsphase](lambda-runtime-environment.md#runtimes-lifecycle-ib) ausgeführt wird. Die `init`-Methode verhält sich in AWS Lambda genauso wie in normalen Go-Programmen.

## Bewährte Codemethoden für Go-Lambda-Funktionen
<a name="go-best-practices"></a>

Halten Sie sich an die Richtlinien in der folgenden Liste, um beim Erstellen Ihrer Lambda-Funktionen die besten Codierungspraktiken anzuwenden:
+ **Trennen Sie den Lambda-Handler von Ihrer Core-Logik.** Auf diese Weise können Sie eine Funktion zur besseren Prüfbarkeit von Einheiten schaffen.
+ **Minimieren Sie die Komplexität Ihrer Abhängigkeiten.** Ziehen Sie einfachere Frameworks vor, die sich schnell beim Start der [Ausführungsumgebung](lambda-runtime-environment.md) laden lassen.
+ **Minimieren Sie die Größe Ihres Bereitstellungspakets auf die für die Laufzeit erforderliche Größe.** Dadurch verkürzt sich die Zeit, die für das Herunterladen und Entpacken Ihres Bereitstellungspakets vor dem Aufruf benötigt wird.

**Nutzen Sie die Wiederverwendung der Ausführungsumgebung zur Verbesserung Ihrer Funktion.** Initialisieren Sie SDK-Clients und Datenbankverbindungen außerhalb des Funktions-Handlers und speichern Sie statische Komponenten lokal im `/tmp`-Verzeichnis. Nachfolgende Aufrufe, die von derselben Instance Ihrer Funktion verarbeitet werden, können diese Ressourcen wiederverwenden. Dies spart Kosten durch Reduzierung der Funktionslaufzeit.

Um potenzielle Datenlecks über Aufrufe hinweg zu vermeiden, verwenden Sie die Ausführungsumgebung nicht, um Benutzerdaten, Ereignisse oder andere Informationen mit Sicherheitsauswirkungen zu speichern. Wenn Ihre Funktion auf einem veränderbaren Zustand beruht, der nicht im Speicher innerhalb des Handlers gespeichert werden kann, sollten Sie für jeden Benutzer eine separate Funktion oder separate Versionen einer Funktion erstellen.

**Verwenden Sie eine Keep-Alive-Direktive, um dauerhafte Verbindungen zu pflegen.** Lambda bereinigt Leerlaufverbindungen im Laufe der Zeit. Der Versuch, eine Leerlaufverbindung beim Aufruf einer Funktion wiederzuverwenden, führt zu einem Verbindungsfehler. Um Ihre persistente Verbindung aufrechtzuerhalten, verwenden Sie die Keep-Alive-Direktive, die Ihrer Laufzeit zugeordnet ist. Ein Beispiel finden Sie unter [Wiederverwenden von Verbindungen mit Keep-Alive in Node.js](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/node-reusing-connections.html).

**Verwenden Sie [Umgebungsvariablen](configuration-envvars.md) um Betriebsparameter an Ihre Funktion zu übergeben.** Wenn Sie z. B. Daten in einen Amazon-S3-Bucket schreiben, anstatt den Bucket-Namen, in den Sie schreiben, hartzucodieren, konfigurieren Sie den Bucket-Namen als Umgebungsvariable.

**Vermeiden Sie rekursive Aufrufe** in Ihrer Lambda-Funktion, bei denen die Funktion sich selbst aufruft oder einen Prozess initiiert, der die Funktion erneut aufrufen kann. Dies kann zu unvorhergesehenen Mengen an Funktionsaufrufen führen und höhere Kosten zur Folge haben. Wenn Sie eine unbeabsichtigte Menge von Aufrufen feststellen, legen Sie die reservierte gleichzeitige Ausführung der Funktion auf `0` fest, um sofort alle Aufrufe der Funktion zu drosseln, während Sie den Code aktualisieren.

**Verwenden Sie keine nicht dokumentierten, nicht öffentlichen APIs** in Ihrem Lambda-Funktionscode. Für AWS Lambda-verwaltete Laufzeiten wendet Lambda regelmäßig Sicherheits- und Funktionsupdates auf Lambdas interne APIs an. Diese internen API-Updates können abwärtskompatibel sein, was zu unbeabsichtigten Konsequenzen wie Aufruffehlern führt, wenn Ihre Funktion von diesen nicht öffentlichen APIs abhängig ist. Eine Liste öffentlich zugänglicher APIs finden Sie in der [API-Referenz](https://docs.aws.amazon.com/lambda/latest/api/welcome.html).

**Schreiben Sie idempotenten Code.** Das Schreiben idempotenter Code für Ihre Funktionen stellt sicher, dass doppelte Ereignisse auf die gleiche Weise behandelt werden. Ihr Code sollte Ereignisse ordnungsgemäß validieren und doppelte Ereignisse ordnungsgemäß behandeln. Weitere Informationen finden Sie unter [Wie mache ich meine Lambda-Funktion idempotent?](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-function-idempotent/).