Skip to content

gRPC Controllers ​

In Sword, a gRPC controller is a struct that implements a trait generated by tonic from a .proto file. This trait defines the gRPC methods the controller must implement.

Defining a Controller ​

rust
use sword::grpc::*;
use sword::prelude::*;

#[controller(kind = Controller::Grpc, service = UserGrpcServiceServer)]
pub struct UsersController;

#[sword::grpc::async_trait]
impl UserGrpcService for UsersController {
    async fn list_users(
        &self,
        req: Request<ListUsersRequest>,
    ) -> GrpcResult<ListUsersReply> {
        tracing::info!("ListUsers gRPC method called");

        Ok(Response::new(ListUsersReply { users: vec![] }))
    }
}

The UserGrpcService trait is generated from a .proto file like the following:

proto
syntax = "proto3";

package users;

service UserGrpcService {
  rpc ListUsers (ListUsersRequest) returns (ListUsersReply);
}

message ListUsersRequest {}

message ListUsersReply {
  repeated UserItem users = 1;
}

message UserItem {
  string id = 1;
  string username = 2;
}

Controller Attributes

The #[controller] Attribute ​

rust
#[controller(kind = Controller::Grpc, service = UserGrpcServiceServer)]

Parameters

  • kind = Controller::Grpc: marks the struct as a gRPC controller.
  • service = UserGrpcServiceServer: tonic-generated server for the service it implements.

The #[sword::grpc::async_trait] Attribute ​

rust
#[sword::grpc::async_trait]
impl UserGrpcService for UsersController { ... }

Just as with plain tonic, this attribute is required to implement the trait generated by tonic: it lets the trait methods be async and be registered correctly in the gRPC server.

When to use it

  • On the implementation of the tonic-generated trait, to enable async methods in traits.

Base Types & Responses

The Request<T> Type ​

rust
pub use tonic::Request;

Returns

  • A tonic wrapper over the incoming request, with access to into_inner() (the message) and metadata().

When to use it

  • As the input type in service methods (for example Request<GetUserRequest>).

The GrpcResult<T> Type ​

rust
pub type GrpcResult<T> = Result<Response<T>, Status>;

Returns

  • Ok(Response<T>) if the call resolves successfully.
  • Err(Status) if the call fails.

When to use it

  • As the return type of service methods.

The GrpcResponse::message() Method ​

rust
pub fn message<T>(value: T) -> tonic::Response<T>

Returns

  • A Response<T> with a single message.

When to use it

  • In unary and client streaming methods to return a typed response.