Skip to content

Commit d26b7ce

Browse files
committed
tRPC/json-rpc: normalize usage
- mimic how McpModule works - make generate code type-safe, so it can't be mixed with normal `rest/mvc` routes - allow `tRPC` to configure base path - fix #3895
1 parent 006d095 commit d26b7ce

File tree

13 files changed

+125
-36
lines changed

13 files changed

+125
-36
lines changed

modules/jooby-apt/src/main/java/io/jooby/internal/apt/JsonRpcRouter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ public String toSourceCode(boolean kt) throws IOException {
203203
.replace("${imports}", imports)
204204
.replace("${className}", generateTypeName)
205205
.replace("${generatedClassName}", generatedClass)
206-
.replace("${implements}", "io.jooby.jsonrpc.JsonRpcService, io.jooby.Extension")
206+
.replace("${implements}", "io.jooby.jsonrpc.JsonRpcService")
207207
.replace("${constructors}", constructors(generatedClass, kt))
208208
.replace("${methods}", trimr(buffer));
209209
}

modules/jooby-apt/src/main/java/io/jooby/internal/apt/TrpcRoute.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ private String trpcPath() {
6161
.flatMap(it -> AnnotationSupport.findAnnotationValue(it, VALUE).stream().findFirst())
6262
.orElse(method.getSimpleName().toString());
6363

64-
return Stream.of("trpc", namespace + procedure)
64+
return Stream.of(namespace + procedure)
6565
.map(segment -> segment.startsWith("/") ? segment.substring(1) : segment)
6666
.collect(Collectors.joining("/", "/", ""));
6767
}
@@ -86,7 +86,8 @@ public List<String> generateMapping(boolean kt, String routerName) {
8686
isSuspendFun() ? "" : "app.",
8787
dslMethod,
8888
"(",
89-
string(path.startsWith("/") ? path : "/" + path),
89+
"path + ",
90+
string(path),
9091
", ",
9192
context.pipeline(
9293
getReturnType().getRawType(), methodReference(kt, thisRef, targetMethod))));

modules/jooby-apt/src/main/java/io/jooby/internal/apt/TrpcRouter.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,12 @@ public String toSourceCode(boolean kt) throws IOException {
100100
buffer.append(indent(4)).append("@Throws(Exception::class)").append(System.lineSeparator());
101101
buffer
102102
.append(indent(4))
103-
.append("override fun install(app: io.jooby.Jooby) {")
103+
.append("override fun install(path: String, app: io.jooby.Jooby) {")
104104
.append(System.lineSeparator());
105105
} else {
106106
buffer
107107
.append(indent(4))
108-
.append("public void install(io.jooby.Jooby app) throws Exception {")
108+
.append("public void install(String path, io.jooby.Jooby app) throws Exception {")
109109
.append(System.lineSeparator());
110110
}
111111

@@ -130,7 +130,7 @@ public String toSourceCode(boolean kt) throws IOException {
130130
.replace("${imports}", imports)
131131
.replace("${className}", generateTypeName)
132132
.replace("${generatedClassName}", generatedClass)
133-
.replace("${implements}", "io.jooby.Extension")
133+
.replace("${implements}", "io.jooby.trpc.TrpcService")
134134
.replace("${constructors}", constructors(generatedClass, kt))
135135
.replace("${methods}", trimr(buffer));
136136
}

modules/jooby-apt/src/test/java/tests/i3863/Issue3863.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ public void trpcQuery() throws Exception {
2424
.withTrpcCode(
2525
source -> {
2626
assertThat(source)
27-
.contains("app.get(\"/trpc/users.getUserById\", this::trpcGetUserById);")
28-
.contains("app.post(\"/trpc/users.createUser\", this::trpcCreateUser);");
27+
.contains("app.get(path + \"/users.getUserById\", this::trpcGetUserById);")
28+
.contains("app.post(path + \"/users.createUser\", this::trpcCreateUser);");
2929
});
3030
}
3131

@@ -36,8 +36,8 @@ public void mixedAnnotation() throws Exception {
3636
source -> {
3737
assertThat(source)
3838
// tRPC
39-
.contains("app.get(\"/trpc/users.getUserById\", this::trpcGetUserById);")
40-
.contains("app.post(\"/trpc/users.createUser\", this::trpcCreateUser);");
39+
.contains("app.get(path + \"/users.getUserById\", this::trpcGetUserById);")
40+
.contains("app.post(path + \"/users.createUser\", this::trpcCreateUser);");
4141
})
4242
.withSourceCode(
4343
source -> {
@@ -55,10 +55,10 @@ public void mixedMutation() throws Exception {
5555
source -> {
5656
assertThat(source)
5757
// tRPC
58-
.contains("app.post(\"/trpc/users.createUser\", this::trpcCreateUser);")
59-
.contains("app.post(\"/trpc/users.updateUser\", this::trpcUpdateUser);")
60-
.contains("app.post(\"/trpc/users.patchUser\", this::trpcPatchUser);")
61-
.contains("app.post(\"/trpc/users.deleteUser\", this::trpcDeleteUser);");
58+
.contains("app.post(path + \"/users.createUser\", this::trpcCreateUser);")
59+
.contains("app.post(path + \"/users.updateUser\", this::trpcUpdateUser);")
60+
.contains("app.post(path + \"/users.patchUser\", this::trpcPatchUser);")
61+
.contains("app.post(path + \"/users.deleteUser\", this::trpcDeleteUser);");
6262
})
6363
.withSourceCode(
6464
source -> {
@@ -78,8 +78,8 @@ public void overloadTrpc() throws Exception {
7878
source -> {
7979
assertThat(source)
8080
// tRPC
81-
.contains("app.get(\"/trpc/users.ping\", this::trpcPing);")
82-
.contains("app.get(\"/trpc/users.ping.since\", this::trpcPingInteger);");
81+
.contains("app.get(path + \"/users.ping\", this::trpcPing);")
82+
.contains("app.get(path + \"/users.ping.since\", this::trpcPingInteger);");
8383
});
8484
}
8585
}

modules/jooby-apt/src/test/java/tests/i3864/Issue3868.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public void topLevelAnnotationMakeAllPublicJSONRPC() throws Exception {
2020
assertThat(source)
2121
.contains(
2222
"public class DefaultMappingRpc_ implements"
23-
+ " io.jooby.jsonrpc.JsonRpcService, io.jooby.Extension {")
23+
+ " io.jooby.jsonrpc.JsonRpcService {")
2424
.contains("public java.util.List<String> getMethods() {")
2525
.contains(
2626
"return java.util.List.of(\"default.rpcMethod1\", \"default.rpcMethod2\")")

modules/jooby-jsonrpc/src/main/java/io/jooby/jsonrpc/JsonRpcModule.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,12 @@
3535
* <p>Usage:
3636
*
3737
* <pre>{@code
38-
* install(new JsonRpcDispatcher());
39-
* services().put(JsonRpcService.class, new MyServiceRpc(new MyService()));
38+
* install(new Jackson3Module());
39+
*
40+
* install(new JsonRpcJackson3Module());
41+
*
42+
* install(new JsonRpcModule(new MyServiceRpc_()));
43+
*
4044
* }</pre>
4145
*
4246
* @author Edgar Espina
@@ -47,11 +51,17 @@ public class JsonRpcModule implements Extension {
4751
private final Map<String, JsonRpcService> services = new HashMap<>();
4852
private final String path;
4953

50-
public JsonRpcModule(String path) {
54+
public JsonRpcModule(String path, JsonRpcService service, JsonRpcService... services) {
5155
this.path = path;
56+
registry(service);
57+
Arrays.stream(services).forEach(this::registry);
58+
}
59+
60+
public JsonRpcModule(JsonRpcService service, JsonRpcService... services) {
61+
this("/rpc", service, services);
5262
}
5363

54-
public void add(JsonRpcService service) {
64+
private void registry(JsonRpcService service) {
5565
for (var method : service.getMethods()) {
5666
this.services.put(method, service);
5767
}

modules/jooby-jsonrpc/src/main/java/io/jooby/jsonrpc/JsonRpcService.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import edu.umd.cs.findbugs.annotations.NonNull;
1111
import io.jooby.Context;
12+
import io.jooby.Jooby;
1213

1314
/**
1415
* Interface for generated JSON-RPC service glue code (*Rpc classes).
@@ -25,6 +26,15 @@ public interface JsonRpcService {
2526
*/
2627
List<String> getMethods();
2728

29+
/**
30+
* Registers the JSON-RPC service with the provided Jooby application.
31+
*
32+
* @param application The Jooby application instance where the JSON-RPC service will be installed.
33+
* Must not be null.
34+
* @throws Exception If registration fails.
35+
*/
36+
void install(@NonNull Jooby application) throws Exception;
37+
2838
/**
2939
* Executes the requested method using the provided context and request data.
3040
*

modules/jooby-jsonrpc/src/main/java/io/jooby/jsonrpc/package-info.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,11 @@
2020
* <p>Usage:
2121
*
2222
* <pre>{@code
23-
* install(new JsonRpcDispatcher());
24-
* services().put(JsonRpcService.class, new MyServiceRpc(new MyService()));
23+
* install(new Jackson3Module());
24+
*
25+
* install(new JsonRpcJackson3Module());
26+
*
27+
* install(new JsonRpcModule(new MyServiceRpc_()));
2528
* }</pre>
2629
*
2730
* @author Edgar Espina

modules/jooby-jsonrpc/src/main/java/module-info.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,11 @@
2020
* <p>Usage:
2121
*
2222
* <pre>{@code
23-
* install(new JsonRpcDispatcher());
24-
* services().put(JsonRpcService.class, new MyServiceRpc(new MyService()));
23+
* install(new Jackson3Module());
24+
*
25+
* install(new JsonRpcJackson3Module());
26+
*
27+
* install(new JsonRpcModule(new MyServiceRpc_()));
2528
* }</pre>
2629
*
2730
* @author Edgar Espina

modules/jooby-trpc/src/main/java/io/jooby/trpc/TrpcModule.java

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
*/
66
package io.jooby.trpc;
77

8+
import java.util.List;
9+
import java.util.stream.Stream;
10+
811
import edu.umd.cs.findbugs.annotations.NonNull;
912
import io.jooby.Extension;
1013
import io.jooby.Jooby;
@@ -28,18 +31,45 @@
2831
* <pre>{@code
2932
* {
3033
* // 1. Install a JSON engine (Prerequisite)
31-
* install(new JacksonModule());
34+
* install(new Jackson3Module())
3235
*
33-
* // 2. Install the tRPC extension
34-
* install(new TrpcModule());
36+
* // 2. JSON implementation of protocol
37+
* install(new TrpcJackson3Module());
3538
*
36-
* // 3. Register your @Trpc annotated controllers
37-
* mvc(new MovieService_());
39+
* // 3. Install the tRPC extension
40+
* install(new TrpcModule(MovieServiceTrpc_()));
3841
* }
3942
* }</pre>
4043
*/
4144
public class TrpcModule implements Extension {
4245

46+
private final String path;
47+
private final List<TrpcService> services;
48+
49+
/**
50+
* Creates a new instance of {@code TrpcModule} with the specified base path and tRPC services.
51+
*
52+
* @param path The base path for all tRPC routes. This is the root URL prefix where all tRPC
53+
* services will be registered. Must not be {@code null}.
54+
* @param service The primary tRPC service to register. Must not be {@code null}.
55+
* @param services Additional tRPC services to register (if any). Optional and may be omitted.
56+
*/
57+
public TrpcModule(String path, TrpcService service, TrpcService... services) {
58+
this.path = path;
59+
this.services = Stream.concat(Stream.of(service), Stream.of(services)).toList();
60+
}
61+
62+
/**
63+
* Constructs a new {@code TrpcModule} with the default base path: <code>trpc</code> and the
64+
* provided services.
65+
*
66+
* @param service The primary tRPC service to register. Must not be {@code null}.
67+
* @param services Additional tRPC services to register (if any). Optional and may be omitted.
68+
*/
69+
public TrpcModule(TrpcService service, TrpcService... services) {
70+
this("/trpc", service, services);
71+
}
72+
4373
/**
4474
* Installs the tRPC extension into the Jooby application.
4575
*
@@ -59,15 +89,19 @@ public class TrpcModule implements Extension {
5989
*/
6090
@Override
6191
public void install(@NonNull Jooby app) throws Exception {
62-
var services = app.getServices();
92+
var registry = app.getServices();
6393

6494
// Ensure a JSON module has provided the necessary parser
65-
services.require(TrpcParser.class);
95+
registry.require(TrpcParser.class);
6696

6797
// Initialize the custom exception mapping registry
68-
services.mapOf(Class.class, TrpcErrorCode.class);
98+
registry.mapOf(Class.class, TrpcErrorCode.class);
6999

70100
// Register the specialized JSON-RPC error formatter
71101
app.error(new TrpcErrorHandler());
102+
103+
for (var service : services) {
104+
service.install(path, app);
105+
}
72106
}
73107
}

0 commit comments

Comments
 (0)