@@ -6,79 +6,95 @@ Http server and client libraries and code generation.
66
77A jax-rs style controllers with annotations (` @Path ` , ` @Get ` ...)
88that is lightweight by using source code generation (annotation processors)
9- to generate adapter code for Javalin and Helidon SE.
9+ to generate adapter code for Javalin and Helidon SE/Nima .
1010
1111- Lightweight as in 65Kb library + generated source code
12- - Full use of Javalin or Helidon SE as desired
12+ - Full use of Javalin or Helidon SE/Nima as desired
1313
1414
15- ## Define a Controller
15+ ## Define a Controller (Note that these APT processors works with both Java and Kotlin.)
1616``` java
17- package org.example.hello
17+ package org.example.hello ;
1818
19- import io.avaje.http.api.Controller
20- import io.avaje.http.api.Get
21- import io.avaje.http.api.Path
19+ import io.avaje.http.api.Controller ;
20+ import io.avaje.http.api.Get ;
21+ import io.avaje.http.api.Path ;
22+ import java.util.List ;
2223
2324@Path (" /widgets" )
2425@Controller
25- class WidgetController (private val hello: HelloComponent) {
26+ public class WidgetController {
27+ private final HelloComponent hello;
28+ public WidgetController (HelloComponent hello ) {
29+ this . hello = hello;
30+ }
31+
32+ @Get (" /{id}" )
33+ Widget getById (int id ) {
34+ return new Widget (id, " you got it" + hello. hello());
35+ }
2636
27- @Get (" /:id " )
28- fun getById ( id : Int ): Widget {
29- return Widget(id , " you got it${hello.hello()} " )
37+ @Get ()
38+ List< Widget > getAll () {
39+ return List . of( new Widget (1 , " Rob " ), new Widget ( 2 , " Fi " ));
3040 }
3141
32- @Get
33- fun getAll (): MutableList < Widget > {
42+ record Widget ( int id , String name ){};
43+ }
3444
35- val list = mutableListOf< Widget > ()
36- list. add(Widget(1 , " Rob" ))
37- list. add(Widget(2 , " Fi" ))
45+ ```
3846
39- return list
40- }
47+ ## Usage with Javalin
4148
42- data class Widget (var id: Int, var name: String)
43- }
49+ The annotation processor will generate controller classes implementing the WebRoutes interface, which means we can
50+ get all the WebRoutes and register them with Javalin using:
51+
52+ ``` java
53+ var routes = BeanScope . builder(). build(). list(WebRoutes . class);
4454
55+ Javalin . create()
56+ .routes(() - > routes. forEach(WebRoutes :: registerRoutes))
57+ .start();
4558```
4659
47- ## Generated source (Javalin )
4860
49- The annotation processor will generate a `$Route` for the controller like below.
61+ ## Usage with Helidon SE
5062
51- Note that this class implements the WebRoutes interface, which means we can
52- get all the WebRoutes and register them with Javalin using .
63+ The annotation processor will generate controller classes implementing the Helidon Service interface, which we can use
64+ get all the Services and register them with Helidon ` RoutingBuilder ` .
5365
5466``` java
55- fun main (args : Array<String > ) {
56-
57- // get all the webRoutes
58- val webRoutes = BeanScope . builder(). build(). list(WebRoutes :: class. java)
67+ var routes = BeanScope . builder(). build(). list(Service . class);
68+ var routingBuilder = Routing . builder(). register(routes. stream(). toArray(Service []:: new ));
69+ WebServer . builder()
70+ .addMediaSupport(JacksonSupport . create())
71+ .routing(routingBuilder)
72+ .build()
73+ .start();
74+ ```
5975
60- val javalin = Javalin . create()
76+ ## Usage with Helidon Nima
6177
62- javalin. routes {
63- // register all the routes with Javalin
64- webRoutes. forEach { it. registerRoutes() }
78+ The annotation processor will generate controller classes implementing the Helidon HttpService interface, which we can use
79+ get all the services and register them with the Helidon `HttpRouting `.
6580
66- // other routes etc as desired
67- ApiBuilder . get(" /foo" ) { ctx - >
68- ctx. html(" bar" )
69- ctx. status(200 )
70- }
71- ...
72- }
81+ ```java
82+ var routes = BeanScope . builder(). build(). list(HttpService . class);
83+ final var builder = HttpRouting . builder();
7384
74- javalin. start(7000 )
85+ for (final HttpService httpService : routes) {
86+ httpService. routing(builder);
7587}
7688
89+ WebServer . builder()
90+ .addRouting(builder. build())
91+ .build()
92+ .start();
7793```
94+ ## Generated sources
7895
7996### (Javalin ) The generated WidgetController $Route . java is:
8097
81-
8298```java
8399package org. example. hello;
84100
@@ -102,7 +118,7 @@ public class WidgetController$Route implements WebRoutes {
102118 @Override
103119 public void registerRoutes () {
104120
105- ApiBuilder . get(" /widgets/:id " , ctx - > {
121+ ApiBuilder . get(" /widgets/{id} " , ctx - > {
106122 int id = asInt(ctx. pathParam(" id" ));
107123 ctx. json(controller. getById(id));
108124 ctx. status(200 );
@@ -117,24 +133,7 @@ public class WidgetController$Route implements WebRoutes {
117133}
118134```
119135
120- ## Generated source (Helidon SE )
121-
122- The annotation processor will generate a `$Route` for the controller like below.
123-
124- Note that this class implements the Helidon Service interface, which means we can
125- get all the Services and register them with Helidon `RoutingBuilder`.
126-
127- ```
128- var routes = BeanScope.builder ().build ().list (Service .class );
129- var routingBuilder = Routing.builder ().register (routes .stream ().toArray (Service []::new ));
130- WebServer.builder ()
131- .addMediaSupport (JacksonSupport .create ())
132- .routing (routingBuilder )
133- .build ()
134- .start ();
135- ```
136136### (Helidon SE ) The generated WidgetController $Route . java is:
137-
138137```java
139138package org. example. hello;
140139
@@ -163,7 +162,7 @@ public class WidgetController$Route implements Service {
163162 @Override
164163 public void update (Routing .Rules rules ) {
165164
166- rules. get(" /widgets/:id " , this :: _getById);
165+ rules. get(" /widgets/{id} " , this :: _getById);
167166 rules. post(" /widgets" , this :: _getAll);
168167 }
169168
@@ -179,6 +178,104 @@ public class WidgetController$Route implements Service {
179178}
180179```
181180
182- Note that this APT processor works with both Java and Kotlin .
181+ ### (Helidon Nima ) The generated WidgetController $Route . java is:
182+
183+ ```java
184+ package org. example. hello;
185+
186+ import static io.avaje.http.api. PathTypeConversion . * ;
187+
188+ import io. avaje. http. api. * ;
189+ import io.avaje.inject. Component ;
190+ import io.helidon.nima.webserver.http. HttpRouting ;
191+ import io.helidon.nima.webserver.http. HttpRules ;
192+ import io.helidon.nima.webserver.http. HttpService ;
193+ import io.helidon.nima.webserver.http. ServerRequest ;
194+ import io.helidon.nima.webserver.http. ServerResponse ;
195+ import org.example.hello. WidgetController ;
196+
197+ @Generated (" avaje-helidon-nima-generator" )
198+ @Component
199+ public class WidgetController $Route implements HttpService {
200+
201+ private final WidgetController controller;
202+ public WidgetController$Route (WidgetController controller ) {
203+ this . controller = controller;
204+ }
205+
206+ @Override
207+ public void routing (HttpRules rules ) {
208+ rules. get(" /widgets/{id}" , this :: _getById);
209+ rules. get(" /widgets" , this :: _getAll);
210+ }
211+
212+ private void _getById (ServerRequest req , ServerResponse res ) {
213+ var pathParams = req. path(). pathParameters();
214+ int id = asInt(pathParams. first(" id" ). get());
215+ var result = controller. getById(id);
216+ res. send(result);
217+ }
218+
219+ private void _getAll (ServerRequest req , ServerResponse res ) {
220+ var pathParams = req. path(). pathParameters();
221+ var result = controller. getAll();
222+ res. send(result);
223+ }
224+
225+ }
226+ ```
227+
228+ ### (Helidon Nima with Avaje - Jsonb ) The generated WidgetController $Route . java is:
183229
230+ ```java
231+ package org. example. hello;
184232
233+ import static io.avaje.http.api. PathTypeConversion . * ;
234+
235+ import io. avaje. http. api. * ;
236+ import io.avaje.inject. Component ;
237+ import io.helidon.nima.webserver.http. HttpRouting ;
238+ import io.helidon.nima.webserver.http. HttpRules ;
239+ import io.helidon.nima.webserver.http. HttpService ;
240+ import io.helidon.nima.webserver.http. ServerRequest ;
241+ import io.helidon.nima.webserver.http. ServerResponse ;
242+ import org.example.hello. WidgetController ;
243+
244+ @Generated (" avaje-helidon-nima-generator" )
245+ @Component
246+ public class WidgetController $Route implements HttpService {
247+
248+
249+ private final WidgetController controller;
250+ private final JsonType<org.example.hello. WidgetController . Widget > getByIdReturnedJsonType;
251+ private final JsonType<java.util.List<org.example.hello. WidgetController . Widget > > getAllReturnedJsonType;
252+
253+ public WidgetController$Route (WidgetController controller , Jsonb jsonB ) {
254+ this . controller = controller;
255+ this . getByIdReturnedJsonType = jsonB. type(org.example.hello. WidgetController . Widget . class);
256+ this . getAllReturnedJsonType = jsonB. type(org.example.hello. WidgetController . Widget . class). list();
257+ }
258+
259+ @Override
260+ public void routing (HttpRules rules ) {
261+ rules. get(" /widgets/{id}" , this :: _getById);
262+ rules. get(" /widgets" , this :: _getAll);
263+ }
264+
265+ private void _getById (ServerRequest req , ServerResponse res ) {
266+ var pathParams = req. path(). pathParameters();
267+ int id = asInt(pathParams. first(" id" ). get());
268+ var result = controller. getById(id);
269+ res. headers(). contentType(io.helidon.common.http. HttpMediaType . APPLICATION_JSON );
270+ getByIdReturnedJsonType. toJson(result, res. outputStream());
271+ }
272+
273+ private void _getAll (ServerRequest req , ServerResponse res ) {
274+ var pathParams = req. path(). pathParameters();
275+ var result = controller. getAll();
276+ res. headers(). contentType(io.helidon.common.http. HttpMediaType . APPLICATION_JSON );
277+ getAllReturnedJsonType. toJson(result, res. outputStream());
278+ }
279+
280+ }
281+ ```
0 commit comments