Wählen Sie Ihre Cookie-Einstellungen aus

Wir verwenden essentielle Cookies und ähnliche Tools, die für die Bereitstellung unserer Website und Services erforderlich sind. Wir verwenden Performance-Cookies, um anonyme Statistiken zu sammeln, damit wir verstehen können, wie Kunden unsere Website nutzen, und Verbesserungen vornehmen können. Essentielle Cookies können nicht deaktiviert werden, aber Sie können auf „Anpassen“ oder „Ablehnen“ klicken, um Performance-Cookies abzulehnen.

Wenn Sie damit einverstanden sind, verwenden AWS und zugelassene Drittanbieter auch Cookies, um nützliche Features der Website bereitzustellen, Ihre Präferenzen zu speichern und relevante Inhalte, einschließlich relevanter Werbung, anzuzeigen. Um alle nicht notwendigen Cookies zu akzeptieren oder abzulehnen, klicken Sie auf „Akzeptieren“ oder „Ablehnen“. Um detailliertere Entscheidungen zu treffen, klicken Sie auf „Anpassen“.

Definieren Sie Lambda-Funktionshandler in Rust

Fokusmodus
Definieren Sie Lambda-Funktionshandler in Rust - AWS Lambda

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.

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.

Anmerkung

Der Rust-Laufzeit-Client ist ein experimentelles Paket. Er kann sich ändern und ist nur zu Evaluierungszwecken gedacht.

Der Lambda-Funktionshandler 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 Rust arbeiten, einschließlich Projektinitialisierung, Benennungskonventionen und Best Practices. Diese Seite enthält auch ein Beispiel für eine Rust-Lambda-Funktion, die Informationen über eine Bestellung aufnimmt, eine Textdateiquittung erstellt und diese Datei in einen Amazon Simple Storage Service (S3) -Bucket legt. Weitere Informationen darüber, wie Sie Ihre Funktion nach dem Schreiben bereitstellen, finden Sie unterBereitstellen von Lambda-Rust-Funktionen mit ZIP-Dateiarchiven.

Richten Sie Ihr Rust-Handler-Projekt ein

Wenn Sie mit Lambda-Funktionen in Rust arbeiten, umfasst der Prozess das Schreiben Ihres Codes, das Kompilieren und das Bereitstellen der kompilierten Artefakte in Lambda. Der einfachste Weg, ein Lambda-Handler-Projekt in Rust einzurichten, ist die Verwendung der AWS Lambda Runtime for Rust. Trotz ihres Namens ist AWS Lambda Runtime for Rust keine verwaltete Laufzeit im gleichen Sinne wie Lambda für Python, Java oder Node.js. Stattdessen ist die AWS Lambda Runtime for Rust eine crate (lambda_runtime), die das Schreiben von Lambda-Funktionen in Rust und die Anbindung an die Ausführungsumgebung AWS Lambda unterstützt.

Verwenden Sie den folgenden Befehl, um AWS Lambda Runtime for Rust zu installieren:

cargo install cargo-lambda

Verwenden Sie nach erfolgreicher Installation den folgenden Befehlcargo-lambda, um ein neues Rust Lambda Function Handler-Projekt zu initialisieren:

cargo lambda new example-rust

Wenn Sie diesen Befehl ausführen, stellt Ihnen die Befehlszeilenschnittstelle (CLI) einige Fragen zu Ihrer Lambda-Funktion:

  • HTTP-Funktion — Wenn Sie beabsichtigen, Ihre Funktion über das API Gateway oder eine Funktions-URL aufzurufen, antworten Sie mit Ja. Andernfalls antworten Sie mit Nein. Im Beispielcode auf dieser Seite rufen wir unsere Funktion mit einem benutzerdefinierten JSON-Ereignis auf und antworten daher mit Nein.

  • Ereignistyp — Wenn Sie eine vordefinierte Ereignisform verwenden möchten, um Ihre Funktion aufzurufen, wählen Sie den richtigen erwarteten Ereignistyp aus. Andernfalls lassen Sie diese Option leer. Im Beispielcode auf dieser Seite rufen wir unsere Funktion mit einem benutzerdefinierten JSON-Ereignis auf, sodass wir diese Option leer lassen.

Nachdem der Befehl erfolgreich ausgeführt wurde, geben Sie das Hauptverzeichnis Ihres Projekts ein:

cd example-rust

Dieser Befehl generiert eine generic_handler.rs Datei und eine main.rs Datei im src Verzeichnis. Der generic_handler.rs kann verwendet werden, um einen generischen Event-Handler anzupassen. Die main.rs Datei enthält Ihre Hauptanwendungslogik. Die Cargo.toml Datei enthält Metadaten zu Ihrem Paket und listet dessen externe Abhängigkeiten auf.

Beispiel für einen Rust Lambda-Funktionscode

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

Beispiel main.rs-Lambda-Funktion
use aws_sdk_s3::{Client, primitives::ByteStream}; use lambda_runtime::{run, service_fn, Error, LambdaEvent}; use serde::{Deserialize, Serialize}; use serde_json::Value; use std::env; #[derive(Deserialize, Serialize)] struct Order { order_id: String, amount: f64, item: String, } async fn function_handler(event: LambdaEvent<Value>) -> Result<String, Error> { let payload = event.payload; // Deserialize the incoming event into Order struct let order: Order = serde_json::from_value(payload)?; let bucket_name = env::var("RECEIPT_BUCKET") .map_err(|_| "RECEIPT_BUCKET environment variable is not set")?; let receipt_content = format!( "OrderID: {}\nAmount: ${:.2}\nItem: {}", order.order_id, order.amount, order.item ); let key = format!("receipts/{}.txt", order.order_id); let config = aws_config::load_defaults(aws_config::BehaviorVersion::latest()).await; let s3_client = Client::new(&config); upload_receipt_to_s3(&s3_client, &bucket_name, &key, &receipt_content).await?; Ok("Success".to_string()) } async fn upload_receipt_to_s3( client: &Client, bucket_name: &str, key: &str, content: &str, ) -> Result<(), Error> { client .put_object() .bucket(bucket_name) .key(key) .body(ByteStream::from(content.as_bytes().to_vec())) // Fixed conversion .content_type("text/plain") .send() .await?; Ok(()) } #[tokio::main] async fn main() -> Result<(), Error> { run(service_fn(function_handler)).await }

Diese main.rs-Datei enthält die folgenden Abschnitte des Codes:

  • useAnweisungen: Verwenden Sie diese, um Rust-Kisten und -Methoden zu importieren, die Ihre Lambda-Funktion benötigt.

  • #[derive(Deserialize, Serialize)]: Definieren Sie die Form des erwarteten Eingabeereignisses in dieser Rust-Struktur.

  • async fn function_handler(event: LambdaEvent<Value>) -> Result<String, Error>: Dies ist die Haupthandler-Methode, die Ihre Hauptanwendungslogik enthält.

  • async fn upload_receipt_to_s3 (...): Dies ist eine Hilfsmethode, auf die von der function_handler Hauptmethode verwiesen wird.

  • #[tokio::main]: Dies ist ein Makro, das den Einstiegspunkt eines Rust-Programms markiert. Es richtet auch eine Tokio-Runtime ein, die es Ihrer main() Methode ermöglicht,async/zu verwenden await und asynchron auszuführen.

  • async fn main() -> Result<(), Error>: Die main() Funktion ist der Einstiegspunkt Ihres Codes. Darin spezifizieren wir function_handler als Haupthandler-Methode.

Die folgende Cargo.toml Datei gehört zu dieser Funktion.

[package] name = "example-rust" version = "0.1.0" edition = "2024" [dependencies] aws-config = "1.5.18" aws-sdk-s3 = "1.78.0" lambda_runtime = "0.13.0" serde = { version = "1", features = ["derive"] } serde_json = "1" tokio = { version = "1", features = ["full"] }

Beispiel für eine Cargo.toml-Datei

Die folgende Cargo.toml Datei gehört zu dieser Funktion.

[package] name = "example-rust" version = "0.1.0" edition = "2024" [dependencies] aws-config = "1.5.18" aws-sdk-s3 = "1.78.0" lambda_runtime = "0.13.0" serde = { version = "1", features = ["derive"] } serde_json = "1" tokio = { version = "1", features = ["full"] }

Damit diese Funktion ordnungsgemäß funktioniert, muss ihre Ausführungsrolle 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.

Gültige Klassendefinitionen für Rust-Handler

In den meisten Fällen haben Lambda-Handler-Signaturen, die Sie in Rust definieren, das folgende Format:

async fn function_handler(event: LambdaEvent<T>) -> Result<U, Error>

Für diesen Handler:

  • Der Name dieses Handlers istfunction_handler.

  • Die Singulareingabe für den Handler ist Event und hat den TypLambdaEvent<T>.

    • LambdaEventist eine Verpackung, die aus der Kiste lambda_runtime stammt. Durch die Verwendung dieses Wrappers erhalten Sie Zugriff auf das Kontextobjekt, das Lambda-spezifische Metadaten wie die Anforderungs-ID des Aufrufs enthält.

    • Tist der deserialisierte Ereignistyp. Dies kann beispielsweise so seinserde_json::Value, dass der Handler jede generische JSON-Eingabe aufnehmen kann. Alternativ kann dies ein Typ sein, z. B. ApiGatewayProxyRequest wenn Ihre Funktion einen bestimmten, vordefinierten Eingabetyp erwartet.

  • Der Rückgabetyp des Handlers istResult<U, Error>.

    • Uist der deserialisierte Ausgabetyp. Umuss den serde::Serialize Traint implementieren, damit Lambda den Rückgabewert in JSON konvertieren kann. Dies U kann beispielsweise ein einfacher Typ wieString, oder eine benutzerdefinierte Struktur seinserde_json::Value, sofern sie implementiert wird. Serialize Wenn Ihr Code eine Ok (U) -Anweisung erreicht, deutet dies auf eine erfolgreiche Ausführung hin, und Ihre Funktion gibt einen Wert vom Typ zurückU.

    • Wenn Ihr Code auf einen Fehler stößt (d. h.Err(Error)), protokolliert Ihre Funktion den Fehler in Amazon CloudWatch und gibt eine Fehlerantwort vom Typ zurückError.

In unserem Beispiel sieht die Handler-Signatur wie folgt aus:

async fn function_handler(event: LambdaEvent<Value>) -> Result<String, Error>

Andere gültige Handler-Signaturen können Folgendes enthalten:

  • Den LambdaEvent Wrapper weglassen — Wenn Sie ihn weglassenLambdaEvent, verlieren Sie den Zugriff auf das Lambda-Kontextobjekt in Ihrer Funktion. Im Folgenden finden Sie ein Beispiel für diese Art von Signatur:

    async fn handler(event: serde_json::Value) -> Result<String, Error>
  • Verwenden des Einheitentyps als Eingabe — Für Rust können Sie den Einheitentyp verwenden, um eine leere Eingabe darzustellen. Dies wird häufig für Funktionen mit regelmäßigen, geplanten Aufrufen verwendet. Im Folgenden finden Sie ein Beispiel für diese Art von Signatur:

    async fn handler(): ()) -> Result<Value, Error>

Namenskonventionen für Handler

Lambda-Handler in Rust haben keine strengen Namensbeschränkungen. Obwohl Sie einen beliebigen Namen für Ihren Handler verwenden können, sind Funktionsnamen in Rust im Allgemeinen in. snake_case

Für kleinere Anwendungen, wie in diesem Beispiel, können Sie eine einzige main.rs Datei verwenden, die Ihren gesamten Code enthält. Bei größeren Projekten main.rs sollte sie den Einstiegspunkt zu Ihrer Funktion enthalten, aber Sie können zusätzliche Dateien dafür verwenden, um Ihren Code in logische Module zu unterteilen. Beispielsweise könnten Sie die folgende Dateistruktur haben:

/example-rust │── src/ │ ├── main.rs # Entry point │ ├── handler.rs # Contains main handler │ ├── services.rs # [Optional] Back-end service calls │ ├── models.rs # [Optional] Data models │── Cargo.toml

Definieren Sie das Eingabeereignisobjekt und greifen Sie darauf zu

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" }

In Rust können Sie die Form des erwarteten Eingabeereignisses in einer Struktur definieren. In diesem Beispiel definieren wir die folgende Struktur zur Darstellung einesOrder:

#[derive(Deserialize, Serialize)] struct Order { order_id: String, amount: f64, item: String, }

Diese Struktur entspricht der erwarteten Eingabeform. In diesem Beispiel generiert das #[derive(Deserialize, Serialize)] Makro automatisch Code für die Serialisierung und Deserialisierung. Das bedeutet, dass wir den generischen Eingabe-JSON-Typ mithilfe der Methode in unsere Struktur deserialisieren können. serde_json::from_value() Dies wird in den ersten Zeilen des Handlers veranschaulicht:

async fn function_handler(event: LambdaEvent<Value>) -> Result<String, Error> { let payload = event.payload; // Deserialize the incoming event into Order struct let order: Order = serde_json::from_value(payload)?; ... }

Sie können dann auf die Felder des Objekts zugreifen. Zum Beispiel holt order.order_id den Wert von order_id aus der ursprünglichen Eingabe.

Vordefinierte Eingabe-Ereignistypen

In der Kiste sind viele vordefinierte Eingabe-Ereignistypen verfügbar. aws_lambda_events Zum Beispiel, wenn Sie beabsichtigen, Ihre Funktion mit API Gateway aufzurufen, einschließlich des folgenden Imports:

use aws_lambda_events::event::apigw::ApiGatewayProxyRequest;

Stellen Sie dann sicher, dass Ihr Haupthandler die folgende Signatur verwendet:

async fn handler(event: LambdaEvent<ApiGatewayProxyRequest>) -> Result<String, Error> { let body = event.payload.body.unwrap_or_default(); ... }

Weitere Informationen zu anderen vordefinierten Eingabe-Ereignistypen finden Sie in der Kiste aws_lambda_events.

Zugreifen auf und Verwenden des Lambda-Kontextobjekts

Das Lambda-Kontextobjekt enthält Informationen über Aufruf, Funktion und Ausführungsumgebung. In Rust enthält der Wrapper das Kontextobjekt. LambdaEvent Sie können beispielsweise das Kontextobjekt verwenden, um die Anforderungs-ID des aktuellen Aufrufs mit dem folgenden Code abzurufen:

async fn function_handler(event: LambdaEvent<Value>) -> Result<String, Error> { let request_id = event.context.request_id; ... }

Weitere Informationen über das Kontextobjekt finden Sie unter Verwenden des Lambda-Kontextobjekts zum Abrufen von Rust-Funktionsinformationen.

Verwenden Sie die AWS SDK for Rust in Ihrem Handler

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 AWS SDK for RustVerwendung von.

Um Ihrer Funktion SDK-Abhängigkeiten hinzuzufügen, fügen Sie sie zu Ihrer Cargo.toml Datei hinzu. Wir empfehlen, nur die Bibliotheken hinzuzufügen, die Sie für Ihre Funktion benötigen. Im Beispielcode zuvor haben wir die verwendetaws_sdk_s3::Client. In der Cargo.toml Datei können Sie diese Abhängigkeit hinzufügen, indem Sie die folgende Zeile unter dem [dependencies] Abschnitt hinzufügen:

aws-sdk-s3 = "1.78.0"
Anmerkung

Dies ist möglicherweise nicht die neueste Version. Wählen Sie die passende Version für Ihre Anwendung.

Importieren Sie dann die Abhängigkeiten direkt in Ihren Code:

use aws_sdk_s3::{Client, primitives::ByteStream};

Der Beispielcode initialisiert dann einen Amazon S3 S3-Client wie folgt:

let config = aws_config::load_defaults(aws_config::BehaviorVersion::latest()).await; let s3_client = Client::new(&config);

Nachdem Sie Ihren SDK-Client initialisiert haben, können Sie ihn verwenden, um mit anderen Diensten zu interagieren. AWS Der Beispielcode ruft die Amazon S3 PutObject S3-API in der upload_receipt_to_s3 Hilfsfunktion auf.

Zugriff auf Umgebungsvariablen

In Ihrem Handler-Code können Sie mithilfe der env::var-Methode auf beliebige Umgebungsvariablen verweisen. In diesem Beispiel verweisen wir mit der folgenden Codezeile auf die definierte RECEIPT_BUCKET-Umgebungsvariable:

let bucket_name = env::var("RECEIPT_BUCKET") .map_err(|_| "RECEIPT_BUCKET environment variable is not set")?;

Geteilten Zustand verwenden

Sie können geteilte Variablen deklarieren, die unabhängig vom Handler-Code Ihrer Lambda-Funktion sind. Diese Variablen können Ihnen helfen, Zustandsinformationen während des Init-Phase zu laden, bevor Ihre Funktion Ereignisse empfängt. Sie können beispielsweise den Code auf dieser Seite ändern, um den Shared State bei der Initialisierung des Amazon S3 S3-Clients zu verwenden, indem Sie die main Funktion und die Handler-Signatur aktualisieren:

async fn function_handler(client: &Client, event: LambdaEvent<Value>) -> Result<String, Error> { ... upload_receipt_to_s3(client, &bucket_name, &key, &receipt_content).await?; ... } ... #[tokio::main] async fn main() -> Result<(), Error> { let shared_config = aws_config::from_env().load().await; let client = Client::new(&shared_config); let shared_client = &client; lambda_runtime::run(service_fn(move |event: LambdaEvent<Request>| async move { handler(&shared_client, event).await })) .await

Bewährte Codemethoden für Rust-Lambda-Funktionen

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 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.

  • Verwenden Sie Umgebungsvariablen 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 APIs in Ihrem Lambda-Funktionscode nicht undokumentiert, nicht öffentlich. Für AWS Lambda verwaltete Laufzeiten führt Lambda regelmäßig Sicherheits- und Funktionsupdates für interne Lambda-Laufzeiten durch. APIs Diese internen API-Updates können abwärtsinkompatibel sein, was zu unbeabsichtigten Folgen wie Aufruffehlern führen kann, wenn Ihre Funktion von diesen nicht öffentlichen Daten abhängig ist. APIs Eine Liste der öffentlich verfügbaren Programme finden Sie in der API-Referenz. APIs

  • 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?.

DatenschutzNutzungsbedingungen für die WebsiteCookie-Einstellungen
© 2025, Amazon Web Services, Inc. oder Tochtergesellschaften. Alle Rechte vorbehalten.