Skip to content

Commit d41c3b3

Browse files
committed
tRPC: remove from 'core'
- remove tRPC from core, including: - annotation `@Trpc` now is on `io.jooby.annotation.trpc` - `jooby-trpc` is now `jooby-trpc-generator` - package `io.jooby.rpc.trpc` is now `io.jooby.trpc` - split `json` bridge into `jooby-trpc-jackson2`, `jooby-trpc-jackson-3`, `jooby-trpc-avaje-jsonb` - fix #3889
1 parent 0f5a11d commit d41c3b3

File tree

64 files changed

+597
-200
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+597
-200
lines changed

docs/asciidoc/tRPC.adoc

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,32 @@
22

33
The tRPC module provides end-to-end type safety by integrating the https://trpc.io/[tRPC] protocol directly into Jooby.
44

5-
Because the `io.jooby.trpc` package is included in Jooby core, there are no extra dependencies to add to your project. This integration allows you to write standard Java/Kotlin controllers and consume them directly in the browser using the official `@trpc/client`—complete with 100% type safety, autocomplete, and zero manual client generation.
5+
Because tRPC is provided in its own module, you will need to add the `jooby-trpc-*` dependencies to your project. This integration allows you to write standard Java/Kotlin controllers and consume them directly in the browser using the official `@trpc/client`—complete with 100% type safety, autocomplete, and zero manual client generation.
66

7-
===== Usage
7+
[dependency, artifactId="jooby-jackson3:Jackson Module, jooby-trpc-jackson3:Trpc Jackson Module, jooby-trpc:Trpc Module"]
8+
.
89

9-
Because tRPC relies heavily on JSON serialization to communicate with the frontend client, a JSON module **must** be installed prior to the `TrpcModule`.
10+
===== Usage
1011

11-
NOTE: Currently, Jooby only provides the required `TrpcParser` SPI implementation for two JSON engines: **Jackson 2/3** and **AvajeJsonbModule**. Using other JSON modules (like Gson) will result in a missing service exception at startup.
12+
Installing tRPC in your Jooby app is a 3-step process. Because tRPC relies heavily on JSON serialization to communicate with the frontend client, you must install a JSON module, followed by its corresponding tRPC bridge module, and finally the core `TrpcModule`.
1213

1314
.Java
1415
[source,java,role="primary"]
1516
----
1617
import io.jooby.Jooby;
1718
import io.jooby.json.JacksonModule;
18-
import io.jooby.rpc.trpc.TrpcModule;
19+
import io.jooby.trpc.TrpcModule;
20+
import io.jooby.trpc.TrpcJackson2Module;
1921
2022
public class App extends Jooby {
2123
{
22-
install(new JacksonModule()); // <1>
24+
install(new Jackson3Module()); // <1>
2325
24-
install(new TrpcModule()); // <2>
26+
install(new TrpcJackson3Module()); // <2>
27+
28+
install(new TrpcModule()); // <3>
2529
26-
trpc(new MovieServiceTrpc_()); // <3>
30+
trpc(new MovieServiceTrpc_()); // <4>
2731
}
2832
}
2933
----
@@ -33,20 +37,24 @@ public class App extends Jooby {
3337
----
3438
import io.jooby.kt.Kooby
3539
import io.jooby.json.JacksonModule
36-
import io.jooby.rpc.trpc.TrpcModule
40+
import io.jooby.trpc.TrpcModule
41+
import io.jooby.trpc.TrpcJackson2Module
3742
3843
class App : Kooby({
39-
install(JacksonModule()) // <1>
44+
install(Jackson3Module()) // <1>
4045
41-
install(TrpcModule()) // <2>
46+
install(TrpcJackson3Module()) // <2>
47+
48+
install(TrpcModule()) // <3>
4249
43-
trpc(MovieServiceTrpc_()) // <3>
50+
trpc(MovieServiceTrpc_()) // <4>
4451
})
4552
----
4653

47-
1. Install a supported JSON engine (Jackson or Avaje)
48-
2. Install the tRPC extension
49-
3. Register your @Trpc annotated controllers (using the APT generated route)
54+
1. Install a supported JSON engine (`Jackson3Module`, `JacksonModule` for Jackson 2, or `AvajeJsonbModule`).
55+
2. Install the corresponding bridge module (`TrcJackson3Module`, `TrpcJackson2Module`, or `TrpcAvajeJsonbModule`).
56+
3. Install the core tRPC extension (`TrpcModule`).
57+
4. Register your `@Trpc` annotated controllers (using the APT generated route).
5058

5159
===== Writing a Service
5260

@@ -58,7 +66,7 @@ You can define your procedures using explicit tRPC annotations or a hybrid appro
5866
.Java
5967
[source,java,role="primary"]
6068
----
61-
import io.jooby.annotation.Trpc;
69+
import io.jooby.annotation.trpc.Trpc;
6270
import io.jooby.annotation.DELETE;
6371
6472
public record Movie(int id, String title, int year) {}
@@ -91,7 +99,7 @@ public class MovieService {
9199
.Kotlin
92100
[source,kotlin,role="secondary"]
93101
----
94-
import io.jooby.annotation.Trpc
102+
import io.jooby.annotation.trpc.Trpc
95103
import io.jooby.annotation.DELETE
96104
97105
data class Movie(val id: Int, val title: String, val year: Int)
@@ -197,7 +205,8 @@ If you throw custom domain exceptions, you can map them directly to tRPC error c
197205
.Java
198206
[source,java,role="primary"]
199207
----
200-
import io.jooby.rpc.trpc.TrpcErrorCode;
208+
import io.jooby.trpc.TrpcModule;
209+
import io.jooby.trpc.TrpcErrorCode;
201210
202211
{
203212
install(new TrpcModule());
@@ -213,8 +222,8 @@ import io.jooby.rpc.trpc.TrpcErrorCode;
213222
[source,kotlin,role="secondary"]
214223
----
215224
import io.jooby.kt.Kooby
216-
import io.jooby.rpc.trpc.TrpcModule
217-
import io.jooby.rpc.trpc.TrpcErrorCode
225+
import io.jooby.trpc.TrpcModule
226+
import io.jooby.trpc.TrpcErrorCode
218227
219228
class App : Kooby({
220229
install(TrpcModule())

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
/* rpc */
1818
exports io.jooby.rpc.jsonrpc;
1919
exports io.jooby.rpc.grpc;
20-
exports io.jooby.rpc.trpc;
2120

2221
uses io.jooby.Server;
2322
uses io.jooby.SslProvider;

modules/jooby-apt/pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@
3838
<scope>test</scope>
3939
</dependency>
4040

41+
<dependency>
42+
<groupId>io.jooby</groupId>
43+
<artifactId>jooby-trpc</artifactId>
44+
<version>${jooby.version}</version>
45+
<scope>test</scope>
46+
</dependency>
47+
4148
<dependency>
4249
<groupId>com.github.victools</groupId>
4350
<artifactId>jsonschema-generator</artifactId>

modules/jooby-apt/src/main/java/io/jooby/apt/JoobyProcessor.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -266,9 +266,9 @@ public Set<String> getSupportedAnnotationTypes() {
266266
supportedTypes.addAll(HttpPath.PATH.getAnnotations());
267267
supportedTypes.addAll(HttpMethod.annotations());
268268
// Add Rcp annotations
269-
supportedTypes.add("io.jooby.annotation.Trpc");
270-
supportedTypes.add("io.jooby.annotation.Trpc.Mutation");
271-
supportedTypes.add("io.jooby.annotation.Trpc.Query");
269+
supportedTypes.add("io.jooby.annotation.trpc.Trpc");
270+
supportedTypes.add("io.jooby.annotation.trpc.Trpc.Mutation");
271+
supportedTypes.add("io.jooby.annotation.trpc.Trpc.Query");
272272
supportedTypes.add("io.jooby.annotation.JsonRpc");
273273
// Add MCP Annotations
274274
supportedTypes.add("io.jooby.annotation.mcp.McpCompletion");

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

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ public void setGeneratedName(String generatedName) {
3030
}
3131

3232
private HttpMethod discoverTrpcMethod() {
33-
if (AnnotationSupport.findAnnotationByName(method, "io.jooby.annotation.Trpc.Query") != null)
34-
return HttpMethod.GET;
35-
if (AnnotationSupport.findAnnotationByName(method, "io.jooby.annotation.Trpc.Mutation") != null)
36-
return HttpMethod.POST;
37-
if (AnnotationSupport.findAnnotationByName(method, "io.jooby.annotation.Trpc") != null) {
33+
if (AnnotationSupport.findAnnotationByName(method, "io.jooby.annotation.trpc.Trpc.Query")
34+
!= null) return HttpMethod.GET;
35+
if (AnnotationSupport.findAnnotationByName(method, "io.jooby.annotation.trpc.Trpc.Mutation")
36+
!= null) return HttpMethod.POST;
37+
if (AnnotationSupport.findAnnotationByName(method, "io.jooby.annotation.trpc.Trpc") != null) {
3838
if (HttpMethod.GET.matches(method)) return HttpMethod.GET;
3939
return HttpMethod.POST;
4040
}
@@ -45,16 +45,16 @@ private String trpcPath() {
4545
var namespace =
4646
Optional.ofNullable(
4747
AnnotationSupport.findAnnotationByName(
48-
method.getEnclosingElement(), "io.jooby.annotation.Trpc"))
48+
method.getEnclosingElement(), "io.jooby.annotation.trpc.Trpc"))
4949
.flatMap(it -> AnnotationSupport.findAnnotationValue(it, VALUE).stream().findFirst())
5050
.map(it -> it + ".")
5151
.orElse("");
5252

5353
var procedure =
5454
Stream.of(
55-
"io.jooby.annotation.Trpc.Query",
56-
"io.jooby.annotation.Trpc.Mutation",
57-
"io.jooby.annotation.Trpc")
55+
"io.jooby.annotation.trpc.Trpc.Query",
56+
"io.jooby.annotation.trpc.Trpc.Mutation",
57+
"io.jooby.annotation.trpc.Trpc")
5858
.map(it -> AnnotationSupport.findAnnotationByName(method, it))
5959
.filter(Objects::nonNull)
6060
.findFirst()
@@ -138,10 +138,10 @@ public List<String> generateHandlerCall(boolean kt) {
138138
innerReactiveType = kt ? "Unit" : "Void";
139139
}
140140
methodReturnTypeString =
141-
rawReactiveType + "<io.jooby.rpc.trpc.TrpcResponse<" + innerReactiveType + ">>";
141+
rawReactiveType + "<io.jooby.trpc.TrpcResponse<" + innerReactiveType + ">>";
142142
} else {
143143
methodReturnTypeString =
144-
"io.jooby.rpc.trpc.TrpcResponse<"
144+
"io.jooby.trpc.TrpcResponse<"
145145
+ (returnType.isVoid() ? (kt ? "Unit" : "Void") : returnTypeString)
146146
+ ">";
147147
}
@@ -173,7 +173,7 @@ public List<String> generateHandlerCall(boolean kt) {
173173
statement(
174174
indent(2),
175175
var(kt),
176-
"parser = ctx.require(io.jooby.rpc.trpc.TrpcParser",
176+
"parser = ctx.require(io.jooby.trpc.TrpcParser",
177177
clazz(kt),
178178
")",
179179
semicolon(kt)));
@@ -433,7 +433,7 @@ public List<String> generateHandlerCall(boolean kt) {
433433
indent(4),
434434
"val ",
435435
parameterName,
436-
"Decoder: io.jooby.rpc.trpc.TrpcDecoder<",
436+
"Decoder: io.jooby.trpc.TrpcDecoder<",
437437
type,
438438
"> = parser.decoder(",
439439
parameter.getType().toSourceCode(kt),
@@ -467,7 +467,7 @@ public List<String> generateHandlerCall(boolean kt) {
467467
buffer.add(
468468
statement(
469469
indent(4),
470-
"io.jooby.rpc.trpc.TrpcDecoder<",
470+
"io.jooby.trpc.TrpcDecoder<",
471471
genericType,
472472
"> ",
473473
parameterName,
@@ -527,39 +527,39 @@ public List<String> generateHandlerCall(boolean kt) {
527527
indent(controllerIndent),
528528
"return ",
529529
call,
530-
".then(reactor.core.publisher.Mono.just(io.jooby.rpc.trpc.TrpcResponse.empty()))",
530+
".then(reactor.core.publisher.Mono.just(io.jooby.trpc.TrpcResponse.empty()))",
531531
semicolon(kt)));
532532
} else if (handler.contains("Mutiny")) {
533533
buffer.add(
534534
statement(
535535
indent(controllerIndent),
536536
"return ",
537537
call,
538-
".replaceWith(io.jooby.rpc.trpc.TrpcResponse.empty())",
538+
".replaceWith(io.jooby.trpc.TrpcResponse.empty())",
539539
semicolon(kt)));
540540
} else if (handler.contains("ReactiveSupport")) {
541541
buffer.add(
542542
statement(
543543
indent(controllerIndent),
544544
"return ",
545545
call,
546-
".thenApply(x -> io.jooby.rpc.trpc.TrpcResponse.empty())",
546+
".thenApply(x -> io.jooby.trpc.TrpcResponse.empty())",
547547
semicolon(kt)));
548548
} else if (handler.contains("Reactivex")) {
549549
buffer.add(
550550
statement(
551551
indent(controllerIndent),
552552
"return ",
553553
call,
554-
".toSingleDefault(io.jooby.rpc.trpc.TrpcResponse.empty())",
554+
".toSingleDefault(io.jooby.trpc.TrpcResponse.empty())",
555555
semicolon(kt)));
556556
} else {
557557
buffer.add(
558558
statement(
559559
indent(controllerIndent),
560560
"return ",
561561
call,
562-
".map(x -> io.jooby.rpc.trpc.TrpcResponse.empty())",
562+
".map(x -> io.jooby.trpc.TrpcResponse.empty())",
563563
semicolon(kt)));
564564
}
565565
} else {
@@ -570,23 +570,23 @@ public List<String> generateHandlerCall(boolean kt) {
570570
indent(controllerIndent),
571571
"return ",
572572
call,
573-
".map { io.jooby.rpc.trpc.TrpcResponse.of(it) }"));
573+
".map { io.jooby.trpc.TrpcResponse.of(it) }"));
574574
} else {
575575
if (handler.contains("ReactiveSupport")) {
576576
buffer.add(
577577
statement(
578578
indent(controllerIndent),
579579
"return ",
580580
call,
581-
".thenApply(io.jooby.rpc.trpc.TrpcResponse::of)",
581+
".thenApply(io.jooby.trpc.TrpcResponse::of)",
582582
semicolon(kt)));
583583
} else if (handler.contains("Mutiny")) {
584584
buffer.add(
585585
statement(
586586
indent(controllerIndent),
587587
"return ",
588588
call,
589-
".onItem().transform(io.jooby.rpc.trpc.TrpcResponse::of)",
589+
".onItem().transform(io.jooby.trpc.TrpcResponse::of)",
590590
semicolon(kt)));
591591
} else {
592592
// Reactor (Mono), RxJava (Single), etc.
@@ -595,7 +595,7 @@ public List<String> generateHandlerCall(boolean kt) {
595595
indent(controllerIndent),
596596
"return ",
597597
call,
598-
".map(io.jooby.rpc.trpc.TrpcResponse::of)",
598+
".map(io.jooby.trpc.TrpcResponse::of)",
599599
semicolon(kt)));
600600
}
601601
}
@@ -605,13 +605,13 @@ public List<String> generateHandlerCall(boolean kt) {
605605
buffer.add(
606606
statement(
607607
indent(controllerIndent),
608-
"return io.jooby.rpc.trpc.TrpcResponse.empty()",
608+
"return io.jooby.trpc.TrpcResponse.empty()",
609609
semicolon(kt)));
610610
} else {
611611
buffer.add(
612612
statement(
613613
indent(controllerIndent),
614-
"return io.jooby.rpc.trpc.TrpcResponse.of(",
614+
"return io.jooby.trpc.TrpcResponse.of(",
615615
call,
616616
nullable ? "!!" : "", // Shared nullability check
617617
")",

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,13 @@ public static TrpcRouter parse(MvcContext context, TypeElement controller) {
3434
continue;
3535
}
3636

37-
if (AnnotationSupport.findAnnotationByName(method, "io.jooby.annotation.Trpc") != null
38-
|| AnnotationSupport.findAnnotationByName(method, "io.jooby.annotation.Trpc.Query")
37+
if (AnnotationSupport.findAnnotationByName(method, "io.jooby.annotation.trpc.Trpc")
3938
!= null
40-
|| AnnotationSupport.findAnnotationByName(method, "io.jooby.annotation.Trpc.Mutation")
39+
|| AnnotationSupport.findAnnotationByName(
40+
method, "io.jooby.annotation.trpc.Trpc.Query")
41+
!= null
42+
|| AnnotationSupport.findAnnotationByName(
43+
method, "io.jooby.annotation.trpc.Trpc.Mutation")
4144
!= null) {
4245

4346
TrpcRoute route = new TrpcRoute(router, method);

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package tests.i3863;
77

88
import io.jooby.annotation.*;
9+
import io.jooby.annotation.trpc.Trpc;
910

1011
@Trpc("users")
1112
public class MixedMutation {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import io.jooby.Context;
99
import io.jooby.annotation.*;
10+
import io.jooby.annotation.trpc.Trpc;
1011

1112
@Trpc("users")
1213
@Path("/api/users")

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*/
66
package tests.i3863;
77

8-
import io.jooby.annotation.Trpc;
8+
import io.jooby.annotation.trpc.Trpc;
99

1010
@Trpc("users")
1111
public class OverloadTrpc {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
package tests.i3863;
77

88
import io.jooby.Context;
9-
import io.jooby.annotation.Trpc;
9+
import io.jooby.annotation.trpc.Trpc;
1010

1111
@Trpc("users")
1212
public class SpecificTrpcAnnotation {

0 commit comments

Comments
 (0)