GithubHelp home page GithubHelp logo

Comments (5)

rlabrecque avatar rlabrecque commented on May 13, 2024 1

Just wanted to throw in my use case for this:

We have a pretty decent REST setup in go, and one thing that I'm missing with tower-grpc is routing. grpc-router above is working alright for my needs now, but I don't think it's going to scale to our REST setup.

The biggest part missing would be the ability to add routes later, and then get a list of the routes.

Here's what I'd want to write:

    let router_service = Router::new(
        GreeterService::new(),
        PingService::new(),
        SomeOtherService::new(),
    );

    // Add the APIListService and HealthCheckService after we created the router_service, and pass
    // it the router_service so that we can get a list of all of the services.
    let api_list_service = APIListService::new(&router_service);
    router_service.add(api_list_service);

    let healthcheck_service = HealthCheckService::new(&router_service);
    router_service.add(healthcheck_service);

    let mut server = Server::new(router_service);

    // Bind server to http2 server and continue as normally
    // ...
#[derive(Clone, Debug)]
pub struct APIListService {
    services: Vec<std::string::String>
}

impl APIListService {
    pub fn new(router: &Router) {
        server::APIListServer::new(APIListService { services: router.get_routes() } )
    }
}

Copied from: tower-rs/tower-grpc#2 (comment)

from tonic.

nytopop avatar nytopop commented on May 13, 2024 1

As I understand it, so that the api_list_service can:

  • have access to all the services registered before it
  • be served on the same server
  • not expose itself, or the healthcheck_service in api list reqs

Although this could be done without involving the router like the following (although it's not super ergonomic):

let greeter = GreeterService::new();
let ping = PingService::new();
let other = SomeOtherService::new();
let api_list = ApiListService::new()
    .with::<GreeterService>()
    .with::<PingService>()
    .with::<SomeOtherService>();
let healthcheck = HealthCheckService::new()
    .with::<GreeterService>()
    .with::<PingService>()
    .with::<SomeOtherService>()
    .with::<ApiListService>();

// boxed version
let router = Router::new()
    .with(greeter)
    .with(ping)
    .with(other)
    .with(api_list)
    .with(healthcheck);

// static version
let router = router! {greeter, ping, other, api_list, healthcheck};

let mut server = Server::new(router);

// Bind server to http2 server and continue as normally
// ...

So long as every service could expose its own routes. I've written a quick PoC that allows that via a trait and associated consts, something like:

pub mod router {
    // every MakeService gets a generated impl for:
    pub trait Routed {
        const PREFIX: &'static str;
        const ROUTES: &'static [&'static str];
    }
}

from tonic.

LucioFranco avatar LucioFranco commented on May 13, 2024

@rlabrecque thanks for opening this!

We've had some ideas there are two that stand out to me currently:

  1. Use a macro to generate the code that looks similar to the one in the interop server.
Server::builder()
	.serve(addr, route! {
		"test_service" => TestService::default(),
		"unimplemented_service" => UnimplementedService::default()
	})
	.await?;
let routed_svc = tonic::Router::new(TestService::default())
	.with(UnimplementedService::default())

Server::builder()
	.serve(addr, routed_svc)
	.await?;

This one is more of an idea, and I'm not sure how to accomplish it without a ton of boxing 😢

from tonic.

LucioFranco avatar LucioFranco commented on May 13, 2024

@rlabrecque what is your use case around needing to add services at a later point?

from tonic.

LucioFranco avatar LucioFranco commented on May 13, 2024

@nytopop That makes sense that was what I was kinda thinking. We can totally add that trait and implement it for codegen. Each async trait impl can include that.

from tonic.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.