Brings the protobuf-based Connect-Web RPC framework to Rust via idiomatic Axum.
Project is under active development for internal use; minor revision bumps are often breaking.
parts that impl RpcFromRequestParts just like
with Axum.RpcIntoResponse just like Axum.RpcIntoResponse and RpcFromRequestParts just like
Axum.
connect-web RPC over HTTP.connect-web error handling in idiomatic Axum/Rust.*.proto files in a separate crate.Prior knowledge with Protobuf (both the IDL and it's use in RPC frameworks) and Axum are assumed.
You'll need 2 axum-connect crates, one for code-gen and one for runtime use.
Because of how prost works, you'll also need to add it to your own project.
You'll obviously also need axum and tokio.
```sh
protoc for you.cargo add --build axum-connect-build cargo add axum-connect prost axum cargo add tokio --features full ```
Start by creating the obligatory 'hello world' proto service definition.
proto/hello.proto
```protobuf syntax = "proto3";
package hello;
message HelloRequest { string name = 1; }
message HelloResponse { string message = 1; }
service HelloWorldService { rpc SayHello(HelloRequest) returns (HelloResponse) {} } ```
Use the axum_connect_codegen crate to generate Rust code from the proto IDL.
Currently all codegen is done by having the proto files locally on-disk, and using a
build.rsfile. Someday I hope to support more of Buf's idioms like Remote Code Gen.
build.rs
```rust use axumconnectbuild::{axumconnectcodegen, AxumConnectGenSettings};
fn main() {
// This helper will use proto as the import path, and globs all .proto
// files in the proto directory. You can build an AxumConnectGenSettings
// manually too, if you wish.
let settings = AxumConnectGenSettings::fromdirectoryrecursive("proto")
.expect("failed to glob proto files");
axumconnectcodegen(settings).unwrap();
}
```
With the boring stuff out of the way, let's implement our service using Axum!
```rust use std::net::SocketAddr;
use axum::{extract::Host, Router}; use axum_connect::prelude::; use proto::hello::;
mod proto { pub mod hello { include!(concat!(env!("OUT_DIR"), "/hello.rs")); } }
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::sayhello(sayhello_success));
// Axum boilerplate to start the server.
let addr = SocketAddr::from(([127, 0, 0, 1], 3030));
println!("listening on http://{}", addr);
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
}
async fn sayhellosuccess( Host(host): Host, request: HelloRequest ) -> HelloResponse { HelloResponse { message: format!( "Hello {}! You're addressing the hostname: {}.", request.name, host ), } } ```
To test it out, try hitting the endpoint manually.
sh
curl --location 'http://localhost:3030/hello.HelloWorldService/SayHello' \
--header 'Content-Type: application/json' \
--data '{ "name": "Alec" }'
From here you can stand up a connect-web TypeScript/Go project to call your
API with end-to-end typed RPCs.
content-typeconnect-webbuf.build to support remote codegen and streamlined proto handlingconnect-web picking up support for the sameaxum-connect highly focused. Good at what it does and
nothing else.The installed version of protoc can be configured in the
AxumConnectGenSettings if you need/wish to do so. Setting the value to None
will disable the download entirely.
Prost stopped shipping protoc binaries (a decision I disagree with) so
axum-connect-build internally uses
protoc-fetcher download and resolve a
copy of protoc. This is far more turnkey than forcing every build environment
(often Heroku and/or Docker) to have a recent protoc binary pre-installed.
This behavior can be disabled if you disagree, you need to comply with corporate
policy, or your build environment is offline.
I would someday like to replace all of it with a new 'lean and mean' protoc library for the Rust community. One with a built-in parser, that supports only the latest proto3 syntax as well as the canonical JSON serialization format and explicitly doesn't support many of the rarely used features. But that day is not today.
axum-connect and axum-connect-build versions are currently not kept in
lockstep. They will be once I get to beta. Right now the versions mean nothing
more than 'Alec pushed a new change'.
Axum-Connect is dual licensed (at your option)