Недавно я построил полный сервис GRP C с Тони c. Мой источник в основном поддерживается в одном файле main.rs, за исключением незначительных модулей зависимости, хотя в целом структура неуправляема. Я пытаюсь определить лучший шаблон для разделения исходного кода, но я сталкиваюсь с препятствиями для модуля.
Вот мой main.rs:
mod myservice;
use tonic::{transport::Server};
use myservice::proto::api_server::{ApiServer};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Build server and individual service
let server = myservice::MyService::new();
let addr = format!("{}:{}", server.opts.host, server.opts.port).parse()?;
let svc = ApiServer::new(server);
// Initialise the service
Server::builder()
.add_service(svc)
.serve(addr)
.await?;
Ok(())
}
Внутри mod.rs внутри моей папки myservice следующее:
pub struct MyService {}
impl MyService {
pub fn new() -> Self { ... }
}
// Service endpoint definitions
#[tonic::async_trait]
impl Api for Void {
async fn endpoint1(&self, request: Request<Location>,) -> Result<Response<Empty>, Status> {
...
}
async fn endpoint2(&self, request: Request<Location>,) -> Result<Response<Empty>, Status> {
...
}
}
В основном, где объявлено async_trait от toni c, все мои конечные точки существуют как функции asyn c. Как правило, так устроен Тони c. В идеале я бы хотел разделить функции asyn c на их собственные подпапки ie. /myservice/endpoint1.rs, /myservice/endpoint2.rs et c.
Проблема этой стратегии заключается в том, что async_trait не будет копировать, не говоря уже о том, что я не уверен, что несколько подисточников разрешено подобное в ржавчине.
Недавно я наткнулся на include!
, который может быть решением для внедрения источника каждой конечной точки в блоке impl Api
. Любые предложения / лучшие практики для обработки этого?