Axum + Connect-Web = ♥️
Find a file
2023-04-28 09:30:29 -07:00
.vscode Add an example React client that points to buf Eliza service 2023-04-03 18:52:47 -07:00
axum-connect Change RpcFromRequestPart impl to non-macro, add State and ConnectInfo 2023-04-28 09:30:29 -07:00
axum-connect-build Add custom rust type resolving for code gen. 2023-03-06 18:10:45 +00:00
axum-connect-examples Change RpcFromRequestPart impl to non-macro, add State and ConnectInfo 2023-04-28 09:30:29 -07:00
.gitignore Initial commit 2023-03-03 04:14:18 +00:00
buf.yaml Add an example React client that points to buf Eliza service 2023-04-03 18:52:47 -07:00
Cargo.toml Initial commit 2023-03-03 04:14:18 +00:00
LICENSE-APACHE Add a readme and license files. 2023-03-03 04:36:10 +00:00
LICENSE-MIT Add a readme and license files. 2023-03-03 04:36:10 +00:00
README.md Add a readme and license files. 2023-03-03 04:36:10 +00:00

Axum Connect-Web

⚠️ This project isn't even Alpha state yet. Don't use it.

Brings the protobuf-based Connect-Web RPC framework to Rust via idiomatic Axum. That means Axum extractors are fully supported, while maintaining strongly typed, contract-driven RPC implementations.

Hello, World!

Prior knowledge with Protobuf (both the IDL and it's use in RPC frameworks) and Axum are assumed.

Starting with the obligatory hello world proto service definition

proto/hello.proto

syntax = "proto3";

package hello_world;

message HelloRequest {
    string name = 1;
}

message HelloResponse {
    string message = 1;
}

service HelloWorldService {
    rpc SayHello(HelloRequest) returns (HelloResponse) {}
}

Axum-Connect code can be generated using axum_connect_codegen

build.rs

use axum_connect_build::axum_connect_codegen;

fn main() {
    axum_connect_codegen("proto", &["proto/hello.proto"]).unwrap();
}

Now we can implement the service contract using handlers that look and behave much like Axum handlers.

use std::net::SocketAddr;

use axum::{extract::Host, Router};
use axum_connect::*;
use proto::hello::{HelloRequest, HelloResponse, HelloWorldService};

mod proto {
    include!(concat!(env!("OUT_DIR"), "/connect_proto_gen/mod.rs"));
}

#[tokio::main]
async fn main() {
    // Build our application with a route. Note the `rpc` method which was added by `axum-connect`.
    // It expect a service method handler, wrapped in it's respective type. The handler (below) is
    // just a normal Rust function. Just like Axum, it also supports extractors!
    let app = Router::new().rpc(HelloWorldService::say_hello(say_hello_handler));

    // Axum boilerplate to start the server.
    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
    println!("listening on http://{}", addr);
    axum::Server::bind(&addr)
        .serve(app.into_make_service())
        .await
        .unwrap();
}

// This is the magic. This is the TYPED handler for the `say_hello` method, changes to the proto
// definition will need to be reflected here. But the first N arguments can be standard Axum
// extracts, to get at what ever info or state you need.
async fn say_hello_handler(Host(host): Host, request: HelloRequest) -> HelloResponse {
    HelloResponse {
        message: format!(
            "Hello {}! You're addressing the hostname: {}.",
            request.name, host
        ),
        special_fields: Default::default(),
    }
}

License

Axum-Connect is dual licensed (at your option)