zurück zum Artikel

Ferris Talk #12: Web-APIs mit Rust erstellen

Rainer Stropek

Dank Frameworks wie Rocket und Axum macht Rust auch jenseits der systemnahen Programmierung beim Gestalten von Web-APIs eine gute Figur.

Rust eignet sich als sichere Alternative zu C gut für die systemnahe Programmierung, ist jedoch keinesfalls darauf beschränkt. Die Programmiersprache und das dazugehörige Ökosystem an Bibliotheken – in Rust Crates genannt – bieten sich ebenso für die Anwendungsentwicklung an. Da Rust durch das Kompilieren in nativen Code sowie durch den Ansatz der Zero-Cost-Abstractions besonders effiziente und performante Anwendungen erzeugen kann, ziehen mehr und mehr Teams die Sprache jenseits von Anwendungsfällen mit besonderer Systemnähe in Betracht.

Ferris Talks – die Kolumne für Rustaceans

Die Entwicklung von Web-APIs ist ein solcher Anwendungsbereich, in dem Rust seine Stärken hinsichtlich Effizienz ausspielen kann. Viele Unternehmen betreiben APIs in der Cloud, und effizienter Code bedeutet dort weniger Ressourcenbedarf und damit geringere monatliche Kosten. Hinzu kommt, dass schnell startende Anwendungen für Serverless Computing wichtig sind, da die Plattform je nach Last dynamisch Serverinstanzen hinzufügt oder entfernt. Ein Serverprozess, der Minuten zum Starten braucht, ist in einer Serverless-Umgebung unbrauchbar. Mit Rust lassen sich auch bei nicht trivialen APIs ohne weiteres Startzeiten deutlich unter einer Sekunde erreichen.

Eine Programmiersprache alleine reicht aber noch nicht, um praxistaugliche Web API-Entwicklung betreiben zu können. Daneben braucht es die richtigen Frameworks, und in dem Bereich gibt es im Umfeld von Rust aktuell viel Bewegung. Im September 2022 kam der zweite Release Candidate des immer populärer werdenden Axum-Frameworks heraus. Der Fortschrittsbalken des Meilensteins für die Version 0.5 des etablierten Rocket-Frameworks steht auf GitHub mittlerweile auf 95 Prozent.

In dieser Ausgabe unserer Kolumne nehmen wir diese Entwicklungen zum Anlass, die Entwicklung von Web-APIs mit Rust zu zeigen. Wir vergleichen dabei die unterschiedlichen API-Ansätze der Frameworks Axum und Rocket und betrachten zum Abschluss den Stand der Dinge in Rust im Vergleich zum ASP.NET-Core-Framework der .NET-Plattform, das unter anderem laut einer aktuellen Stack-Overflow-Umfrage [16] zu den verbreitetsten Webframeworks weltweit gehört.

Neben Axum und Rocket gibt es noch zahlreiche weitere Frameworks für die Web-API-Entwicklung in Rust. Vielfalt ist ein charakteristischer Wesenszug des Rust-Ökosystems. Eine komplettere Liste von Frameworks für Webentwicklung mit Rust findet man auf den Webseiten Are We Web Yet [17] und Awesome Rust [18]. Dieser Artikel konzentriert sich ausschließlich auf HTTP-Web-APIs und behandelt keine APIs mit anderen Protokollen wie Websockets oder gRPC.

Naturgemäß spielt asynchrone Programmierung eine wichtige Rolle bei der Entwicklung von Web-APIs. Um diese Herausforderung zu meistern, bauen Axum und Rocket sowie andere populäre Web-API-Frameworks wie Actix Web und Warp auf Tokio auf [19]. Dabei handelt es sich im Kern um eine Laufzeitumgebung für asynchrones Programmieren in Rust mit darauf aufbauenden Erweiterungen. Eine solche Basis ist wichtig, da Rust für die asynchrone Entwicklung zwar die grundlegenden Abstraktionen wie Futures bietet, die asynchrone Laufzeitumgebung jedoch anders als bei anderen Sprachen wählbar und austauschbar ist. Mit der asynchronen Programmierung in Rust beschäftigt sich ein früherer Ferris-Talk-Beitrag [20].

Obwohl sowohl Axum als auch Rocket Tokio als Basis haben, unterscheiden sie sich in der Tiefe der Integration stark. Rocket verwendet Tokio im Hintergrund: Beim Entwickeln kommt man nicht zwangsläufig mit Tokio in Berührung. Im Gegensatz dazu ist Axum direkt im Tokio-Technologie-Stack zu Hause. Das Team hinter dem Framework versucht nicht, Tokio zu verstecken, sondern betrachtet die enge Einbindung in Tokio-Technologien wie Tower als Stärke. Das ist ein Pluspunkt für diejenigen, die Tokio gut kennen und vielleicht sogar schon beispielsweise Tower-basierende HTTP-Middleware-Komponenten entwickelt haben.

Ein weiteres Unterscheidungsmerkmal von Web-API-Frameworks auf Rust-Basis ist der Einsatz von Makros. Wir haben bewusst zwei Frameworks gewählt, die in dieser Hinsicht unterschiedlich sind. Die Rocket-API ist geprägt von Makros, die an allen Ecken und Enden zum Einsatz kommen, um die Entwicklung von Web-APIs zu vereinfachen. Im Gegensatz dazu kommt die Axum-API komplett ohne Makros aus. Sie ist deshalb nicht automatisch schwieriger zu erlernen oder weniger angenehm in der Handhabung. Die APIs der beiden Frameworks sind einfach von Grund auf unterschiedlich gestaltet. Wer kein Problem mit Makros in Rust hat, kann beide Frameworks gleichermaßen verwenden. Wer jedoch auf Makros weitgehend verzichten möchte, tendiert wahrscheinlich zu Axum.

Die Heise-Konferenz zu Rust

Am 9. November findet die zweite Auflage der betterCode() Rust statt [21]. Die Online-Konferenz fokussiert sich dieses Jahr auf einen praxisnahen Einstieg in die Programmiersprache Rust. Die von heise Developer und dpunkt.verlag ausgerichtete Veranstaltung vermittelt in sechs Vorträgen [22] die Grundlagen, um Desktop- und WebAssembly-Anwendungen oder Web-APIs zu erstellen, ohne sich in der Komplexität der Tiefen von Rust zu verlieren.

Zum Thema Web-APIs gibt es nicht nur einen Vortrag, sondern Rainer Stropke, der Autor dieses Artikels, bietet einen Workshop für diejenigen an [23], die tiefer in das Thema einsteigen und selbst Hand anlegen möchten.

Wie viele Makros die jeweiligen APIs verwenden, ist übrigens eine Unterscheidung, die über Rocket und Axum hinausgeht. Die Frameworks Actix Web und Warp setzen beispielsweise Makros ein, jedoch deutlich sparsamer als Rocket, und sie bieten alternative API-Varianten ohne Makros an.

Um die Unterschiede und Gemeinsamkeiten von Rocket und Axum kennenzulernen, dient im Folgenden auszugsweise Beispielcode für eine RESTful-Web-API zur Verwaltung einer To-do-Liste. Der Code setzt die üblichen Operationen wie Hinzufügen, Abfragen, Ändern und Löschen um. Die Web-API-Schnittstelle ist für beide Frameworks identisch. Der komplette Quellcode steht auf GitHub zur Verfügung [24]. Das Repository enthält nicht nur den Code für Rocket und Axum, sondern darüber hinaus Implementierungen mit Actix Web, Warp und Spin, einem auf WebAssembly basierenden Framework.

Wie andere zeitgemäße Webframeworks benötigt Rust keinen externen Webserver. Eine Web-API ist technisch gesehen eine Kommandozeilenanwendung, die über die zugrundeliegenden Komponenten (Crates) Webserver und dazugehörige Technologien wie TLS-Verschlüsselung der übertragenen Daten mitbringt.

Bei Rocket markiert man die Einstiegsmethode mit dem Makro launch, das die main-Methode (asynchron dank Tokio) erzeugt:

/// Type for our shared state
///
/// In our sample application, we store the to-do
/// list in memory. As the state is shared 
/// between concurrently running web requests, 
/// we need to make it thread-safe. 
type Db = Arc<RwLock<TodoStore>>;

/// Rocket relies heavily on macros. 
/// The launch macro will generate a
/// tokio main function for us.
#[launch]
fn rocket() -> _ {
  // Initialize logging.
  // Rocket uses the log crate 
  // (https://crates.io/crates/log) to log requests. 
  // You can use any compatible logger, but for 
  // this example we'll use simplelog.
  // Enhancements in terms
  // of more flexible logging are planned 
  // for future releases
  // (https://github.com/SergioBenitez/Rocket/issues/21).
  SimpleLogger::init(LevelFilter::Debug, 
                     Config::default()).unwrap();

  // Create shared data store
  let db = Db::default();

  rocket::build()
    // Here we mount our routes. More details
    // about route mounting at 
    // https://rocket.rs/v0.5-rc/guide/overview/#mounting.
    .mount(
      "/",
      routes![get_todos, get_todo, add_todo, 
              update_todo, delete_todo, persist],
    )
    // Register our shared state.
    // More about using shared state at 
    // https://rocket.rs/v0.5-rc/guide/state/.
    .manage(db)
}

Der Code zeigt, wie intensiv Rocket auf Makros setzt. Neben dem launch-Makro findet man ein weiteres wichtiges Makro namens routes im Aufruf der mount-Methode. Dort erfolgt die Registrierung der API-Handler für die Web-API-Endpunkte.

Folgender Ausschnitt zeigt im Vergleich den Code zum Starten der Web-API in Axum:

/// Type for our shared state
///
/// In our sample application, we store the 
/// to-do list in memory. As the state is shared 
/// between concurrently running web requests, 
/// we need to make it thread-safe. 
type Db = Arc<RwLock<TodoStore>>;

#[tokio::main]
async fn main() {
  // Enable tracing using Tokio's tracing crate
  // (https://tokio.rs/#tk-lib-tracing)
  tracing_subscriber::registry()
    .with(tracing_subscriber::EnvFilter::new(
      std::env::var("RUST_LOG")
        .unwrap_or_else(
          |_| "todo_axum=debug,tower_http=debug".into()),
    ))
    .with(tracing_subscriber::fmt::layer())
    .init();

  // Create shared data store
  let db = Db::default();

  // We register our shared state so that 
  // handlers can get it using the State extractor.
  // Note that this will change in Axum 0.6. See more at
  // https://docs.rs/axum/0.6.0-rc.2/axum/
  //   index.html#sharing-state-with-handlers
  let app = Router::with_state(db)
    // Here we set up the routes. Note: no macros
    .route("/todos", get(get_todos).post(add_todo))
    .route("/todos/:id", 
           delete(delete_todo)
             .patch(update_todo)
             .get(get_todo))
    .route("/todos/persist", post(persist))
    // Using tower to add tracing layer
      .layer(ServiceBuilder::new()
               .layer(TraceLayer::new_for_http())
               .into_inner());

  let addr = SocketAddr::from(([0, 0, 0, 0], 3000));
  axum::Server::bind(&addr)
    .serve(app.into_make_service()).await.unwrap();
}

Auch wenn die Codepassagen von Rocket und Axum konzeptionell ähnlich sind, unterscheidet sich die Umsetzung deutlich. Zunächst ist erkennbar, dass Axum keine Makros einsetzt. Das einzige Makro im Code ist tokio::main, das nicht von Axum kommt. Das Framework verbirgt es aber nicht, da es bewusst dicht mit dem Tokio-Stack verwoben ist. Die enge Beziehung ist auch beim Logging sichtbar: Axum verwendet die tracing-Crate von Tokio. Die Logging-Middleware ist als Service mit den Tower-Crates aus dem Tokio-Stack umgesetzt und lässt sich daher in Axum verwenden, wie im Aufruf der Methode layer ersichtlich ist. Ebenso lassen sich andere Tower-Services in Verbindung mit Axum nutzen.

Nachdem der Server gestartet ist, folgen die API-Handler und das Routing. Da sich die Codebeispiele auf die ausgewählten Web-API-Frameworks konzentrieren, ist die eigentliche Verwaltungslogik der To-do-Liste in eine eigene Bibliothek ausgelagert, die im GitHub-Repository des Autors [25] zu finden ist. Die folgenden API-Handler-Methoden rufen die Funktionen der Bibliothek auf.

Los geht es mit den Methoden zum Abrufen von To-do-Einträgen im Rocket-Framework:

/// Get list of to-do items
///
/// Rocket implements the FromParam trait 
/// for typically used data types so they can
/// be used to extract data from the query string.
/// Of course you can implement
/// FromParam for custom data types, too.
/// More about it at 
/// https://rocket.rs/v0.5-rc/guide/requests/#query-strings.
///
/// The shared state is extracted using the State request
/// guard. Mmore about Rocket's request guards at
/// https://rocket.rs/v0.5-rc/guide/requests/
///   #request-guards.
/// 
/// Also note the Responder trait 
/// https://rocket.rs/v0.5-rc/guide/responses/
      #custom-responders).
/// Rocket comes with a lot of built-in responders, 
/// but you can also implement the trait for your 
/// own custom types.
#[get("/todos?<offset>&<limit>")]
async fn get_todos(offset: Option<usize>, 
                   limit: Option<usize>, 
                   db: &State<Db>) 
  -> Json<Vec<IdentifyableTodoItem>> 
{
  let todos = db.read().await;
  let pagination = Pagination::new(offset, limit);
  Json(todos.get_todos(pagination))
}

/// Get a single to-do item
///
/// Note that Option<T> implements the 
/// Responder trait, too. This makes it really
/// simple to return a 404 if the requested 
/// item does not exist.
#[get("/todos/<id>")]
async fn get_todo(id: usize, db: &State<Db>) 
  -> Option<Json<IdentifyableTodoItem>> 
{
  let todos = db.read().await;
  todos.get_todo(id).map(|item| Json(item.clone()))
}

In Rocket dienen Makros dazu, die Routen der API-Handler-Methoden zu definieren. Der Code verwendet das get-Makro, um Daten abzufragen. Analog dazu gibt es Makros für andere HTTP-Verben wie post und delete. Rocket kann Parameter sowohl im Pfad der URL als auch im Query String verarbeiten. Die Basis für das Extrahieren von Informationen aus der URL ist der Trait FromParam. Jeder Rust-Typ, der ihn implementiert, lässt sich für URL-Parameter verwenden. Rocket bringt fertige Implementierungen für gängige Rust-Datentypen mit. Das schließt auch den Option-Typ ein, mit dem sich optionale Parameter modellieren lassen. Für komplexere Szenarien kann man zudem FromParam individuell für eigene Datentypen implementieren.

Besonders erwähnenswert ist der Parameter db. Dabei kommt ein zentrales Konzept von Rocket zum Einsatz – Request Guards: Typen, die den FromRequest-Trait implementieren. Sie schützen API-Handler, indem sie prüfen, ob benötigte Informationen – im konkreten Beispiel der Shared State – zur Verfügung stehen. Sie stellen diese Daten anschließend den Handler-Methoden zur Verfügung. Weitere typische Anwendungsbeispiele für Request Guards wären der Zugriff auf Cookies und das Prüfen von JSON Web Tokens (JWT).

Das Ergebnis der obigen Handler-Methoden ist eine JSON-Response. Rocket kennt dafür die Struktur Json, die sich sowohl als Request Guard zum Extrahieren von JSON-Daten aus dem Request Body als auch in Form des Responder zur Rückgabe von JSON-Daten im Response Body verwenden lässt. Zum Serialisieren und Deserialisieren kommt sowohl in Axum als auch in Rocket die dafür vorgesehene Serde-Crate zum Einsatz.

Folgender Code zeigt als Vergleich zur Rocket-Implementierung die Umsetzung der Handler-Methoden zur Datenabfrage mit Axum:

/// Get list of to-do items
///
/// Note how the Query extractor is used to get 
/// query parameters (more about extractors at
/// https://docs.rs/axum/latest/axum/#extractors).
/// Note how the State extractor is used to get 
/// the database (will change in Axum 0.6 RC).
/// Extractors are types that implement FromRequest. 
/// You can create your own extractors or use 
/// the ones provided by Axum.
async fn get_todos(pagination: Option<Query<Pagination>>, 
                   State(db): State<Db>) 
  -> impl IntoResponse 
{
  let todos = db.read().await;
  let Query(pagination) = pagination.unwrap_or_default();
  // Json is an extractor and a response.
  Json(todos.get_todos(pagination))
}

/// Get a single to-do item
///
/// Note how the Path extractor is used 
/// to get query parameters.
async fn get_todo(Path(id): Path<usize>, 
                  State(db): State<Db>) 
  -> impl IntoResponse 
{
  let todos = db.read().await;
  if let Some(item) = todos.get_todo(id) {
    // Note how to return Json
    Json(item).into_response()
  } else {
    // Note how a tuple can be turned into a response
    (StatusCode::NOT_FOUND, "Not found").into_response()
  }
}

Ein Unterschied zwischen Rocket und Axum sticht sofort ins Auge: Das Routing geschieht nicht durch Makros bei der Handler-Methode, sondern war bereits in der zuvor gezeigten main-Methode zu finden. Ansonsten ähneln sich die Konzepte. Extractors dienen in Axum dazu, Daten aus der URL zu extrahieren. Technisch gesehen handelt es sich dabei um Typen, die den Trait FromRequest implementieren. Wie Rocket kommt Axum mit FromRequest-Implementierungen für viele, häufig verwendete Einsatzfälle. Ein nützliches Detail ist dabei in der Methode get_todos zu sehen. Statt die Query-Parameter einzeln angeben zu müssen, verwendet man eine Struktur (Pagination), die alle Query-Parameter empfängt.

Das Erzeugen des Ergebnisses, also der HTTP Response Message, basiert bei Axum auf dem IntoResponse-Trait. Handler-Methoden können jeden Typ zurückgeben, der diesen Trait implementiert. Für JSON steht ähnlich wie bei Rocket die Json-Struktur bereit, die sowohl Extractor als auch Responder ist, um JSON sowohl im Request als auch im Response Body verarbeiten zu können.

Mehr zum Umgang mit JSON in Zusammenhang mit HTTP Requests ist in der Handler-Methode zum Hinzufügen von To-do-Einträgen erkennbar. Folgender Code zeigt die Implementierung in Rocket:

/// Add a new to-do item
///
/// Note the use of a "Request Guard" (FromRequest
/// trait) here. Here it is used to extract the 
/// JSON body of the request. You can implement 
/// your own guards, too
/// (https://rocket.rs/v0.5-rc/guide/requests/
///   #custom-guards). Many things that you
/// would do with middleware in other frameworks are 
/// done with request guards in Rocket.
#[post("/todos", format = "json", data = "<todo>")]
async fn add_todo(todo: Json<TodoItem>, 
                  db: &State<Db>) 
  -> Created<Json<IdentifyableTodoItem>> 
{
  let mut todos = db.write().await;
  let todo = todos.add_todo(todo.0);

  // Nice detail here: The uri macro helps you 
  // generate URIs for your routes.
  // Very useful for building the location header.
  let location = uri!("/", get_todo(todo.id));
  Created::new(location.to_string()).body(Json(todo))
}

Das post-Makro erlaubt die Angabe, dass die Methode Daten im JSON-Format erwartet, die in den Parameter todo eingetragen werden sollen. Beim Datentyp Json handelt es sich um die gleiche Struktur, die oben bereits beim Zusammenstellen der JSON Response Message zum Einsatz kam.

Ein schönes Detail ist das Erstellen der Created Response Message. Rocket bietet eine eigene Struktur mit zugehörigem Makro an, die das Erstellen des bei RESTful-Web-APIs üblichen Location-Headers [26] vereinfacht.

Bei Axum sieht die Handler-Methode, die To-do-Elemente hinzufügt, ähnlich aus:

/// Add a new to-do item
///
/// Note that this time, Json is used as an extractor. 
/// That means that the request body
/// will be deserialized into a TodoItem.
async fn add_todo(State(db): State<Db>, 
                  Json(todo): Json<TodoItem>) 
  -> impl IntoResponse 
{
  let mut todos = db.write().await;
  let todo = todos.add_todo(todo);
  (StatusCode::CREATED, Json(todo))
}

Die Umsetzungen der Methode add_todo zeigen erneut, dass die beiden Frameworks konzeptionell ähnlich sind, wenn es darum geht, die eigentliche API-Logik umzusetzen. Größere Unterschiede gibt es beim API-Design, darunter die Rolle von Makros und die Integration in den Tokio-Stack sowie beim Aufbau der zentralen Abstraktionen, auf denen die beiden Frameworks aufbauen, wie Request Guards bei Rocket versus Extractors bei Axum.

Die restlichen API-Methoden setzen ebenso auf die vorgestellten Konzepte. Der vollständige Sourcecode findet sich in dem GitHub-Repository zum Artikel.

Für die Auswahl des Frameworks zum Entwickeln einer umfangreichen Web-API spielen nicht nur technische Aspekte eine Rolle. Punkte wie Dokumentation, Wartung, regelmäßige Erweiterungen oder eine lebendige Community sind bedeutend, da man eine langfristige Bindung eingeht.

In Sachen Dokumentation gibt es bei beiden Frameworks nicht viel auszusetzen. Rocket bietet eine umfangreiche Anleitung [27], die weit über die reine API-Dokumentation hinausgeht. Axum hinkt bei dem Punkt einen Tick hinterher. Die konzeptionelle Erklärung ist in die Dokumentation der Crate [28] eingebettet und nicht so umfangreich wie bei Rocket, aber ausreichend. Beim Beispielcode ist es umgekehrt: Beide Frameworks liefern im jeweiligen GitHub-Repository Beispiele für viele Anwendungsfälle mit, und bei Axum ist die Beispielsammlung eine Spur umfangreicher als bei Rocket.

Was die Weiterentwicklung betrifft, sind die Unterschiede größer. Die Beliebtheit von Axum ist gemessen an den Downloadzahlen auf crates.io seit dem Start des Projekts stark gestiegen. Das Framework ist deutlich jünger als Rocket, hat aber bezüglich der Downloadzahlen bereits eindeutig die Nase vorn. Für Axum erscheinen regelmäßig neue Versionen. Im Vergleich dazu ist der erste Release Candidate (RC) von Rocket 0.5 bereits über ein Jahr und der aktuelle RC2 ein halbes Jahr alt. Die Entwicklung von Rocket schreitet somit momentan langsamer voran als die von Axum.

Der wahrscheinlich wichtigste Unterschied in Sachen Zukunftssicherheit der Frameworks ist die enge Einbindung von Axum in das Tokio-Projekt gegenüber der loseren Kopplung bei Rocket. Ein gutes Beispiel dafür ist das Middleware-System beider Frameworks. Während Rocket mit den Request Guards und den Fairings (mehr dazu im iX-Artikel "Rostige Raketen" [29]) eigene Konzepte mitbringt, verzichtet Axum auf ein eigenes Middleware-Konzept und baut auf dem Tower-Projekt von Tokio auf. Letzteres ist in der Rust-Welt zu einem zentralen Baustein geworden, und die enge Verzahnung wird sich bei anhaltendem Erfolg von Tokio positiv auf Axum auswirken.

Einige mögen sich wegen der wachsenden Aufmerksamkeit für Rust fragen, ob sie ihr angestammtes Web-API-Framework beiseite legen und in Zukunft auf Rust setzen sollen. Obwohl durch Frameworks wie Rocket und Axum die API-Entwicklung in Rust abseits der systemnahen Softwareentwicklung auf jeden Fall machbar und sinnvoll geworden ist, ist der Funktionsumfang noch nicht mit dem von älteren und weit verbreiteten Frameworks wie ASP.NET Core vergleichbar. Funktionen wie das Generieren einer Open-API-Spezifikation (Swagger), fertige Komponenten für gängige Authentifizierungsplattformen oder nahtlose Integration anderer Protokolle wie gRPC sind in Rust nicht vorhanden, oder man muss sich eigenhändig Umsetzungen dafür bauen beziehungsweise zusammensuchen.

Man könnte vermuten, dass Rust diesen Nachteil durch Performancevorteile aufwiegen kann. Was für zahlreiche Projekte gelten mag, ist jedoch nicht zwangsläufig der Fall. In den aktuellen TechEmpower Web Framework Benchmarks [30] liegen Axum und ASP.NET Core Kopf an Kopf auf den Plätzen 8 und 9. Rocket ist zumindest bei diesem Benchmark nicht im Spitzenfeld zu finden. Beim Vergleich von Frameworks anhand von Benchmarks ist allerdings Vorsicht geboten: Oft lassen sich allgemeine Ergebnisse nicht auf konkrete Projekte übertragen. Außerdem ist zu bedenken, dass Axum im Vergleich zu ASP.NET Core ein Jungspund ist. Da Rust sich durch hervorragende Effizienz auszeichnet, ist zu erwarten, dass es bei Axum noch einiges an Optimierungspotenzial gibt. Im Vergleich dazu müssen etablierte Plattformen wie ASP.NET Core fundamentale Veränderungen andenken [31], um beispielsweise durch Ahead-of-Time-Übersetzung Startup-Zeiten noch weiter zu verbessern und Anwendungen noch wesentlich zu verkleinern.

Wer die Sprache Rust schätzen gelernt hat, braucht vor einem Einsatz im Bereich der Entwicklung von Web-APIs nicht zurückschrecken. Es gibt etablierte und funktionsreiche Frameworks, die Entwicklerinnen und Entwickler mit genügend Basiswissen in Rust und Webentwicklung schnell erlernen können. Die exemplarisch betrachteten Frameworks Rocket und Axum weisen konzeptionelle Ähnlichkeiten auf, jedoch auch deutliche Unterschiede in der Ausgestaltung der API und der Einbindung in den Tokio-Stack.

Das Potenzial für die Zukunft von Rust zum Entwickeln verteilter Systeme ist groß. Selbst junge Frameworks wie Axum spielen in Sachen Performance schon jetzt in einer Liga mit den am verbreitetsten Webframeworks wie ASP.NET Core. Angesichts der Entwicklungsdynamik im Umfeld von Rust und der wachsenden Verbreitung der Sprache ist man gut beraten, bei neuen Projekten über den Tellerrand zu schauen und Rust bei der nächsten API eine Chance zu geben.

Ferris Talk – Neuigkeiten zu Rust. Kolumnist:
Rainer Stropek, timecockpit.com, Rust Meetup Linz, Autor der Ferris Talks, der Kolumne über die Programmiersprache Rust bei Heise Developer

Rainer Stropek

ist Softwareentwickler, Trainer, Autor und Vortragender im Microsoft-Umfeld und seit über 25 Jahren als Unternehmer in der IT-Industrie tätig.

Er gründete und führte in dieser Zeit mehrere IT-Dienstleistungsunternehmen. Neben der Tätigkeit als Trainer und Berater in seiner Firma software architects [32] entwickelt er mit seinem Team die preisgekrönte Software time cockpit [33]. Rainer hat Abschlüsse der höheren technischen Schule für Informatik Leonding (AT) sowie der University of Derby (UK). Er ist Autor mehrerer Fachbücher und Artikel in Magazinen im Umfeld von Microsoft .NET und C#, Azure, Go und Rust. Seine technischen Schwerpunkte sind Cloud Computing, die Entwicklung verteilter Systeme sowie Datenbanksysteme.

Regelmäßig tritt er als Speaker und Trainer auf namhaften Konferenzen in Europa und den USA auf. 2010 wurde er von Microsoft zu einem der ersten MVPs (Most Valuable Professionals) für die Azure-Plattform ernannt. Seit 2015 ist er Microsoft Regional Director. 2016 hat er zudem den MVP Award für Visual Studio und Developer Technologies erhalten.

(rme [34])


URL dieses Artikels:
https://www.heise.de/-7321340

Links in diesem Artikel:
[1] https://www.heise.de/hintergrund/Ferris-Talk-1-Iteratoren-in-Rust-6175409.html
[2] https://www.heise.de/hintergrund/Ferris-Talk-2-Abstraktionen-ohne-Mehraufwand-Traits-in-Rust-6185053.html
[3] https://www.heise.de/hintergrund/Ferris-Talk-3-Neue-Rust-Edition-2021-ist-da-mit-Disjoint-Capture-in-Closures-6222248.html
[4] https://www.heise.de/hintergrund/Ferris-Talk-4-Asynchrone-Programmierung-in-Rust-6299096.html
[5] https://www.heise.de/hintergrund/Ferris-Talk-5-Tokio-als-asynchrone-Laufzeitumgebung-ist-ein-Fast-Alleskoenner-6341018.html
[6] https://www.heise.de/hintergrund/Ferris-Talk-6-Ein-neuer-Trick-fuer-die-Formatstrings-in-Rust-6505377.html
[7] https://www.heise.de/hintergrund/Ferris-Talk-7-Vom-Ungetuem-zur-Goldrose-eine-kleine-Rust-Refactoring-Story-6658167.html
[8] https://www.heise.de/hintergrund/Ferris-Talk-8-Wasm-loves-Rust-WebAssembly-und-Rust-jenseits-des-Browsers-7064040.html
[9] https://www.heise.de/hintergrund/Ferris-Talk-9-Vom-Builder-Pattern-und-anderen-Typestate-Abenteuern-7134143.html
[10] https://www.heise.de/hintergrund/Ferris-Talk-10-Constant-Fun-mit-Rust-const-fn-7162074.html
[11] https://www.heise.de/hintergrund/Ferris-Talk-11-Memory-Management-Speichermanagement-in-Rust-mit-Ownership-7195773.html
[12] https://www.heise.de/hintergrund/Ferris-Talk-12-Web-APIs-mit-Rust-erstellen-7321340.html
[13] https://www.heise.de/hintergrund/Ferris-Talk-13-Rust-Web-APIs-und-Mocking-mit-Axum-7457143.html
[14] https://www.heise.de/hintergrund/Ferris-Talk-14-Rust-bekommt-endlich-asynchrone-Methoden-in-Traits-8929334.html
[15] https://www.heise.de/hintergrund/Ferris-Talk-15-Bedingte-Kompilierung-in-Rust-9337115.html
[16] https://survey.stackoverflow.co/2022/#technology-most-popular-technologies
[17] https://www.arewewebyet.org/topics/frameworks/
[18] https://github.com/rust-unofficial/awesome-rust#web-programming
[19] https://www.heise.de/hintergrund/Ferris-Talk-5-Tokio-als-asynchrone-Laufzeitumgebung-ist-ein-Fast-Alleskoenner-6341018.html
[20] https://www.heise.de/hintergrund/Ferris-Talk-4-Asynchrone-Programmierung-in-Rust-6299096.html
[21] https://rust.bettercode.eu/
[22] https://rust.bettercode.eu/index.php#programm
[23] https://rust.bettercode.eu/veranstaltung-15497-se-0-web-apis-mit-rust-erstellen.html
[24] https://github.com/rstropek/rust-api-fxs
[25] https://github.com/rstropek/rust-api-fxs
[26] https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Location
[27] https://rocket.rs/v0.5-rc/guide/
[28] https://docs.rs/axum/0.6.0-rc.2/axum/index.html
[29] https://www.heise.de/select/ix/2021/5/2106710094242146958
[30] https://www.techempower.com/benchmarks/#section=data-r21
[31] https://twitter.com/davidfowl/status/1582955638736695296
[32] https://www.linkedin.com/company/software-architects-og/about/
[33] https://www.timecockpit.com/
[34] mailto:rme@ix.de