Skip to content

Commit 18e1d84

Browse files
committed
better doc for route props and mapper
1 parent ec2aa62 commit 18e1d84

File tree

4 files changed

+212
-12
lines changed

4 files changed

+212
-12
lines changed

coverage-report/src/test/java/org/jooby/issues/Issue349.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ public void ignored() {
3939
.get("/a", () -> "a")
4040
.map(v -> "//" + v);
4141

42+
with(() -> {
43+
44+
get("/double", () -> 2);
45+
46+
get("/str", req -> "str");
47+
}).map((final Integer v) -> v * 2);
48+
4249
}
4350

4451
@Test
@@ -63,7 +70,14 @@ public void mapper() throws Exception {
6370

6471
request().get("/mvc/void")
6572
.expect(204);
66-
6773
}
6874

75+
@Test
76+
public void applyIntMapper() throws Exception {
77+
request().get("/double")
78+
.expect("4");
79+
80+
request().get("/str")
81+
.expect("str");
82+
}
6983
}

jooby/src/main/java/org/jooby/Route.java

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,74 @@
214214
*/
215215
public interface Route {
216216

217+
/**
218+
* The map operator converts a route output to something else
219+
*
220+
* <pre>{@code
221+
* {
222+
* // we got bar.. not foo
223+
* get("/foo", () -> "foo")
224+
* .map(value -> "bar");
225+
*
226+
* // we got foo.. not bar
227+
* get("/bar", () -> "bar")
228+
* .map(value -> "foo");
229+
* }
230+
* }</pre>
231+
*
232+
* If you want to apply a single map to several routes:
233+
*
234+
* <pre>{@code
235+
* {
236+
* with(() -> {
237+
* get("/foo", () -> "foo");
238+
*
239+
* get("/bar", () -> "bar");
240+
*
241+
* }).map(v -> "foo or bar");
242+
* }
243+
* }</pre>
244+
*
245+
* You can apply a {@link Mapper} to specific return type:
246+
*
247+
* <pre>{@code
248+
* {
249+
* with(() -> {
250+
* get("/str", () -> "str");
251+
*
252+
* get("/int", () -> 1);
253+
*
254+
* }).map(String v -> "{" + v + "}");
255+
* }
256+
* }</pre>
257+
*
258+
* A call to <code>/str</code> produces <code>{str}</code>, while <code>/int</code> just
259+
* <code>1</code>.
260+
*
261+
* <strong>NOTE</strong>: You can apply the map operator to routes that produces an output.
262+
*
263+
* For example, the map operator will be silently ignored here:
264+
*
265+
* <pre>{@code
266+
* {
267+
* get("/", (req, rsp) -> {
268+
* rsp.send(...);
269+
* }).map(v -> ..);
270+
* }
271+
* }</pre>
272+
*
273+
* @author edgar
274+
* @param <T> Type to map.
275+
*/
217276
interface Mapper<T> {
277+
278+
/**
279+
* Map the type to something else.
280+
*
281+
* @param value Value to map.
282+
* @return Mapped value.
283+
* @throws Throwable If mapping fails.
284+
*/
218285
Object map(T value) throws Throwable;
219286
}
220287

jooby/src/main/java/org/jooby/internal/MappedHandler.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
119
package org.jooby.internal;
220

321
import static javaslang.API.Case;

md/route-attrs.md

Lines changed: 112 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
1-
## attributes
1+
## properties
22

3-
It is possible to add metadata to routes via ```.attr(String, String)```:
3+
Routes have a few properties that let you extend basic functionality in one way or another including:
4+
5+
* attributes
6+
* with, map and excludes operators
7+
* consumes/produces types.
8+
9+
### attributes
10+
11+
Attributes let you annotated a route at application bootstrap time. It is like static metadata available at runtime:
412

513
```java
614
{
@@ -9,7 +17,9 @@ It is possible to add metadata to routes via ```.attr(String, String)```:
917
}
1018
```
1119

12-
You can add as many attributes as you need. They can be accessed later and use it in one way or another. For example, a security module might looks for ```role``` attribute, a sitemap generator might like for ```priority``` attribute, etc...
20+
An attribute consist of a name and value. Allowed values are ```primitives```, ```String```, ```enum```, ```class``` or an ```array``` of previous types.
21+
22+
Attributes can be accessed at runtime in a request/response cycle. For example, a security module might check for ```role``` attribute, a sitemap generator might check for ```priority``` attribute, etc...
1323

1424
```java
1525
{
@@ -25,7 +35,17 @@ You can add as many attributes as you need. They can be accessed later and use i
2535
}
2636
```
2737

28-
In MVC routes we use ```annotations``` to define route attributes:
38+
In MVC routes you can set attributes for all the web methods:
39+
40+
```java
41+
{
42+
use(Controller.class)
43+
.attr("foo", "bar");
44+
}
45+
```
46+
47+
48+
Or via ```annotations```:
2949

3050
```java
3151
@Target({ElementType.METHOD, ElementType.TYPE, ElementType.ANNOTATION_TYPE })
@@ -65,9 +85,81 @@ Any runtime annotations are automatically added as route attributes. Following t
6585
>
6686
> While, request attributes are created in a request/response cycle.
6787
88+
### with operator
89+
90+
The with operator set attributes, consumes and produces types, exclusions, etc.. to one or more routes:
91+
92+
```java
93+
{
94+
with(() -> {
95+
96+
get("/admin/1", ...);
97+
98+
get("/admin/2", ...);
99+
100+
}).attr("role", "admin");
101+
}
102+
```
103+
104+
### map operator
105+
106+
The map operator converts a route output to something else
107+
108+
```java
109+
{
110+
// we got bar.. not foo
111+
get("/foo", () -> "foo")
112+
.map(value -> "bar");
113+
114+
// we got foo.. not bar
115+
get("/bar", () -> "bar")
116+
.map(value -> "foo");
117+
}
118+
```
119+
120+
If you want to apply a single map to several routes:
121+
122+
```java
123+
{
124+
with(() -> {
125+
get("/foo", () -> "foo");
126+
127+
get("/bar", () -> "bar");
128+
129+
}).map(v -> "foo or bar");
130+
}
131+
```
132+
133+
You can apply a [Mapper]({{defdocs}}/Route.Mapper.html) to specific types:
134+
135+
```java
136+
{
137+
with(() -> {
138+
get("/str", () -> "str");
139+
140+
get("/int", () -> 1);
141+
142+
}).map(String v -> "{" + v + "}");
143+
}
144+
```
145+
146+
A call to ```/str``` produces ```{str}```, while ```/int``` just ```1```.
147+
148+
> **NOTE**: You can apply the map operator to routes that produces an output.
149+
150+
For example, the map operator will be silently ignored here:
151+
152+
```java
153+
{
154+
get("/", (req, rsp) -> {
155+
rsp.send(...);
156+
});
157+
}
158+
```
159+
68160
### excludes
69161

70-
The excludes attribute skip/ignore a route path match:
162+
The excludes operator skip/ignore a route path match:
71163

72164
```java
73165
{
@@ -77,18 +169,27 @@ The excludes attribute skip/ignore a route path match:
77169
}
78170
```
79171

80-
### with
172+
### consumes
81173

82-
The with operator help to set common attributes, consumes and produces types, exclusions, etc.. to one or more routes:
174+
The consumes operator indicates the expected input the route can handle. It is used will accepting requests.
83175

84176
```java
85177
{
86-
with(() -> {
178+
post("/", req -> {
179+
MyObject json = req.body().to(MyObject.class);
87180

88-
get("/admin/1", ...);
181+
}).consumes("json");
182+
}
183+
```
89184

90-
get("/admin/2", ...);
185+
### produces
91186

92-
}).attr("role", "admin");
187+
The produces operator indicates the expected output the route can produces.
188+
189+
```java
190+
{
191+
get("/", req -> {
192+
return new MyObject();
193+
}).produces("json");
93194
}
94195
```

0 commit comments

Comments
 (0)