RxRpc: End-to-end asynchronus ReactiveX-based RPC framework for Java and TypeScript
WORK IN PROGRESS...
Goal
To provide easy-to-use asynchronous RPC framework, oriented for Java backend and Java/TypeScript client
Features:
- Fully asynchronous (both client and server side)
- Automated client code generation for Java and TypeScript
- Custom dependency injection framework support
- WebSockets support
Getting started
Server side
Endpoint definition:
Endpoint is defined by class, annotated with @RxRpcEndpoint
annotation. Each RPC method is annotated with @RxRpcMethod
Return types:
Following return types are allowed:
- Asynchronous types
Observable<T>
Single<T>
Maybe<T>
Completable
Publisher<T>
Future<T>
- Any other type will be handled as synchronous (from server side) invocation
Endpoint definition example
@RxRpcEndpoint
public interface SayHelloEndpoint {
@RxRpcMethod
Observable<String> sayHello(String name);
}
public class SayHelloEndpointImpl implements SayHelloEndpoint {
public Observable<String> sayHello(String name) {
Observable.just("Hello, " + name).delay(2, TimeUnit.SECONDS);
}
}
Jetty-based embedded server, serving the endpoint, defined above
public class SampleServer {
private final Server jetty;
private final JettyWebSocketRxTransport.Server transportServer = JettyWebSocketRxTransport
.builder()
.buildServer();
private final RxServer rxServer;
public SampleServer(int port) {
this.jetty = createJetty(port);
this.rxServer = RxServer.configBuilder()
.server(transportServer) // Use jetty WebSocket-servlet based transport
.discoverModules() // Discover auto-generated endpoint modules
.resolver(ServiceResolvers
.builder()
.bind(SayHelloEndpoint.class).to(SayHelloEndpointImpl.class)
.build())
.createServer();
}
public void start() throws Exception {
this.jetty.start();
this.rxServer.start();
}
public void stop() throws Exception {
this.rxServer.stop();
this.jetty.stop();
}
public void join() throws InterruptedException {
this.jetty.join();
}
private Server createJetty(int port) {
Server jetty = new Server(port);
ServletContextHandler context = new ServletContextHandler();
context.setContextPath("/");
ServletHolder servletHolder = new ServletHolder(transportServer);
context.addServlet(servletHolder, "/api/");
jetty.setHandler(context);
return jetty;
}
}
Client side
Java client example
RxClient rxClient = RxClient.forClient(JettyWebSocketRxTransport.builder().buildClient());
SayHelloEndpoint sayHelloClient = rxClient.connect(uri).resolve(SayHelloEndpoint_RxClient.class);
sayHelloClient
.sayHello("Alice")
.test()
.awaitDone(1000, TimeUnit.MILLISECONDS)
.assertValueCount(1)
.assertValue("Hello, Alice");