Skip to content

Commit f55087d

Browse files
authored
Update README.md
1 parent 634b4f2 commit f55087d

File tree

1 file changed

+101
-58
lines changed

1 file changed

+101
-58
lines changed

README.md

Lines changed: 101 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -6,79 +6,95 @@ Http server and client libraries and code generation.
66

77
A jax-rs style controllers with annotations (`@Path`, `@Get` ...)
88
that 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-
27-
@Get("/:id")
28-
fun getById(id : Int): Widget {
29-
return Widget(id, "you got it${hello.hello()}")
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());
3035
}
3136

3237
@Get
33-
fun getAll(): MutableList<Widget> {
34-
35-
val list = mutableListOf<Widget>()
36-
list.add(Widget(1, "Rob"))
37-
list.add(Widget(2, "Fi"))
38-
39-
return list
38+
List<Widget> getAll() {
39+
return List.of(new Widget(1, "Rob"), new Widget(2, "Fi"));
4040
}
4141

42-
data class Widget(var id: Int, var name: String)
42+
record Widget(int id, String name){};
4343
}
4444

4545
```
4646

47-
## Generated source (Javalin)
47+
## Usage with Javalin
4848

49-
The annotation processor will generate a `$Route` for the controller like below.
50-
51-
Note that this class implements the WebRoutes interface, which means we can
52-
get all the WebRoutes and register them with Javalin using.
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:
5351

5452
```java
55-
fun main(args: Array<String>) {
53+
var routes = BeanScope.builder().build().list(WebRoutes.class);
5654

57-
// get all the webRoutes
58-
val webRoutes = BeanScope.builder().build().list(WebRoutes::class.java)
55+
Javalin.create()
56+
.routes(() -> routes.forEach(WebRoutes::registerRoutes))
57+
.start();
58+
```
5959

60-
val javalin = Javalin.create()
6160

62-
javalin.routes {
63-
// register all the routes with Javalin
64-
webRoutes.forEach { it.registerRoutes() }
61+
## Usage with Helidon SE
6562

66-
// other routes etc as desired
67-
ApiBuilder.get("/foo") { ctx ->
68-
ctx.html("bar")
69-
ctx.status(200)
70-
}
71-
...
72-
}
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`.
65+
66+
```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+
```
7375

74-
javalin.start(7000)
76+
## Usage with Helidon Nima
77+
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 `RoutingBuilder`.
80+
81+
```java
82+
var routes = BeanScope.builder().build().list(HttpService.class);
83+
final var builder = HttpRouting.builder();
84+
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
8399
package 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,23 +133,52 @@ public class WidgetController$Route implements WebRoutes {
117133
}
118134
```
119135

120-
## Generated source (Helidon SE)
136+
### (Helidon SE) The generated WidgetController$Route.java is:
137+
```java
138+
package org.example.hello;
121139

122-
The annotation processor will generate a `$Route` for the controller like below.
140+
import static io.avaje.http.api.PathTypeConversion.*;
123141

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`.
142+
import io.avaje.http.api.*;
143+
import io.helidon.common.http.FormParams;
144+
import io.helidon.webserver.Handler;
145+
import io.helidon.webserver.Routing;
146+
import io.helidon.webserver.ServerRequest;
147+
import io.helidon.webserver.ServerResponse;
148+
import io.helidon.webserver.Service;
149+
import jakarta.inject.Singleton;
150+
import org.example.hello.WidgetController;
126151

152+
@Generated("io.dinject.helidon-generator")
153+
@Singleton
154+
public class WidgetController$Route implements Service {
155+
156+
private final WidgetController controller;
157+
158+
public WidgetController$Route(WidgetController controller) {
159+
this.controller = controller;
160+
}
161+
162+
@Override
163+
public void update(Routing.Rules rules) {
164+
165+
rules.get("/widgets/{id}", this::_getById);
166+
rules.post("/widgets", this::_getAll);
167+
}
168+
169+
private void _getById(ServerRequest req, ServerResponse res) {
170+
int id = asInt(req.path().param("id"));
171+
res.send(controller.getById(id));
172+
}
173+
174+
private void _getAll(ServerRequest req, ServerResponse res) {
175+
res.send(controller.getAll());
176+
}
177+
178+
}
127179
```
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-
```
136-
### (Helidon SE) The generated WidgetController$Route.java is:
180+
181+
### (Helidon Nima) The generated WidgetController$Route.java is:
137182

138183
```java
139184
package org.example.hello;
@@ -163,7 +208,7 @@ public class WidgetController$Route implements Service {
163208
@Override
164209
public void update(Routing.Rules rules) {
165210

166-
rules.get("/widgets/:id", this::_getById);
211+
rules.get("/widgets/{id}", this::_getById);
167212
rules.post("/widgets", this::_getAll);
168213
}
169214

@@ -179,6 +224,4 @@ public class WidgetController$Route implements Service {
179224
}
180225
```
181226

182-
Note that this APT processor works with both Java and Kotlin.
183-
184227

0 commit comments

Comments
 (0)