Skip to content

Commit 02f1fe8

Browse files
committed
greeting and jdbi guides
1 parent 46cfc4a commit 02f1fe8

6 files changed

Lines changed: 749 additions & 841 deletions

File tree

md/guides/greeting.md

Lines changed: 390 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,390 @@
1+
{{#unless website}}[![Build Status](https://travis-ci.org/jooby-guides/{{guide}}.svg?branch=master)](https://travis-ci.org/jooby-guides/{{guide}}){{/unless}}
2+
# greeting
3+
4+
You will learn how to build a simple **JSON API** with {{javadoc "Jooby"}}.
5+
6+
The service will be available at:
7+
8+
```
9+
http://localhost:8080/greeting
10+
```
11+
12+
and respond with `JSON` response:
13+
14+
```json
15+
{
16+
"id": 1,
17+
"name": "Hello World!"
18+
}
19+
```
20+
21+
{{jooby}} offers two programming model:
22+
23+
* **script**, where routes are writing via **DSL** and lambdas.
24+
* **mvc**, where routes are writing as class method and annotations.
25+
26+
In this guide you will learn how to write a simple **JSON API** using both models.
27+
28+
# requirements
29+
30+
Make sure you have all these software installed it in your computer:
31+
32+
* A text editor or IDE
33+
* {{java}} or later
34+
* {{maven}}
35+
36+
# ready
37+
38+
Open a terminal/console and paste:
39+
40+
```bash
41+
mvn archetype:generate -B -DgroupId={{pkgguide}} -DartifactId={{guide}} -Dversion=1.0 -DarchetypeArtifactId=jooby-archetype -DarchetypeGroupId=org.jooby -DarchetypeVersion={{version}}
42+
```
43+
44+
A simple `hello world` application is ready to run. Try now:
45+
46+
```
47+
cd {{guide}}
48+
49+
mvn jooby:run
50+
```
51+
52+
Open a browser and type:
53+
54+
```
55+
http://localhost:8080
56+
```
57+
58+
> **TIP**: If you make a change `jooby:run` automatically restart and reload your application. More at {{link "/doc/devtools" "development tools"}}.
59+
60+
# quick preview
61+
62+
Before moving forward let's have a look at `App.java`:
63+
64+
```java
65+
package {{guide}};
66+
67+
import org.jooby.Jooby;
68+
69+
public class App extends Jooby { // 1 extends Jooby
70+
71+
{
72+
// 2 define some routes
73+
get("/", () -> "Hello World!");
74+
}
75+
76+
public static void main(final String[] args) {
77+
// 3 run this app
78+
run(App::new, args);
79+
}
80+
81+
}
82+
```
83+
84+
That's all you need to get up and running a simple **Hello World** {{javadoc "Jooby"}} application.
85+
86+
# script route
87+
88+
Now we already see how a {{javadoc "Jooby"}} application looks like, we are going to create a simple greeting **JSON API**:
89+
90+
First `Greeting.java`:
91+
92+
```java
93+
{{source "Greeting.java"}}
94+
```
95+
96+
## create a route
97+
98+
Go to `App.java` and add this line:
99+
100+
```java
101+
{
102+
get("/greeting", () -> new Greeting("Hello World!"));
103+
}
104+
```
105+
106+
Try it:
107+
108+
```
109+
http://localhost:8080/greeting
110+
```
111+
112+
You'll see `Hello World!` in your browser, not bad ugh?
113+
114+
Not bad at all! But if you look closely we send a `text/html` response not an `application/json` response.
115+
116+
Before building **JSON** response let's see how to read a HTTP parameter.
117+
118+
## adding a name parameter
119+
120+
We are going to improve our service by allowing a name parameter:
121+
122+
```java
123+
...
124+
{
125+
...
126+
get("/greeting", req -> {
127+
String name = "Hello " + req.param("name").value() + "!";
128+
129+
return new Greeting(name);
130+
});
131+
}
132+
```
133+
134+
HTTP parameters are accessible via {{javadoc "Request" "param" "java.lang.String"}} method, that is why we change a bit our route to access the {{javadoc "Request"}} object.
135+
136+
Try it:
137+
138+
```
139+
http://localhost:8080/greeting?name=Jooby
140+
```
141+
142+
What if you call the service without a ```name```? You will get a ```Bad Request(400)``` response. Let's fix that with an ```Optional``` parameter:
143+
144+
```java
145+
...
146+
{
147+
...
148+
get("/greeting", req -> {
149+
String name = "Hello " + req.param("name").value("World") + "!";
150+
151+
return new Greeting(name);
152+
});
153+
}
154+
```
155+
156+
Same as before, we ask for the HTTP parameter but this time we set a default value: ```World```.
157+
158+
The {{javadoc "Mutant" "value" "java.lang.String"}} is syntax sugar for:
159+
160+
```
161+
String name = req.param("name").toOptional().orElse("World");
162+
```
163+
164+
Optional parameters are represented by `java.util.Optional`.
165+
166+
Try it with a parameter:
167+
168+
http://localhost:8080/greeting?name=Jooby
169+
170+
Try it without a parameter:
171+
172+
http://localhost:8080/greeting
173+
174+
## path parameter
175+
176+
If you want or prefer a ```path``` parameter, you can replace the path pattern with: ```/greeting/:name``` or allow both of them:
177+
178+
```java
179+
...
180+
{
181+
...
182+
get("/greeting", "/greeting/:name", req -> {
183+
String name = "Hello " + req.param("name").value("World") + "!";
184+
185+
return new Greeting(name);
186+
});
187+
}
188+
```
189+
190+
Try it with a path parameter:
191+
192+
```
193+
http://localhost:8080/greeting/Jooby
194+
```
195+
196+
Try it with a query parameter:
197+
198+
```
199+
http://localhost:8080/greeting?name=Jooby
200+
```
201+
202+
Nice ugh?
203+
204+
# json
205+
206+
{{jooby}} is a micro-web framework in order to write a **JSON** response we need one of the available {{link "/doc/parser-and-renderer" "json modules"}}.
207+
208+
Here we will use {{modlink "jackson"}} but keep in mind the process is exactly the same if you choose any other module.
209+
210+
## dependency
211+
212+
Let's add the {{modlink "jackson"}} dependency to your project:
213+
214+
```xml
215+
<dependency>
216+
<groupId>org.jooby</groupId>
217+
<artifactId>jooby-jackson</artifactId>
218+
<version>{{version}}</version>
219+
</dependency>
220+
```
221+
222+
If `jooby:run` is running, please restart it. We need to force a restart due we added a new dependency.
223+
224+
## use
225+
226+
Let's {{javadoc "Jooby" "use" "org.jooby.Jooby.Module" label="use"}} the module in our `App.java`:
227+
228+
```java
229+
230+
import org.jooby.json.Jackson;
231+
...
232+
233+
{
234+
use(new Jackson());
235+
236+
...
237+
238+
get("/greeting", "/greeting/:name", req -> {
239+
String name = "Hello " + req.param("name").value("World") + "!";
240+
241+
return new Greeting(name);
242+
});
243+
}
244+
```
245+
246+
Our service method didn't change at all! we just {{javadoc "Jooby" "use" "org.jooby.Jooby.Module" label="use"}} the {{modlink "jackson"}} module!!
247+
248+
Try it
249+
250+
http://localhost:8080/greeting
251+
252+
You will get a nice **JSON** response:
253+
254+
```json
255+
{
256+
"id": 1,
257+
"name": "Hello World!"
258+
}
259+
```
260+
261+
# mvc route
262+
263+
As a learning **exercise** we will build the same service using the **MVC** programming model.
264+
265+
## create a route
266+
267+
Create a new `Greetings.java` class like:
268+
269+
```java
270+
package greeting;
271+
272+
import org.jooby.mvc.Path;
273+
import org.jooby.mvc.GET;
274+
275+
@Path("/mvc")
276+
public class Greetings {
277+
278+
@Path("/greeting")
279+
@GET
280+
public String greeting() {
281+
return "Hello World!";
282+
}
283+
}
284+
```
285+
286+
The **MVC** programming model is similar to {{spring}} and/or {{jersey}}, except a `MVC` routes must be registered at at application startup time.
287+
288+
## registering a mvc route
289+
290+
Go to `App.java` and add this line:
291+
292+
```java
293+
{
294+
...
295+
296+
use(Greetings.class);
297+
}
298+
```
299+
300+
We try to keep `reflection`, `classpath scanning` and `annotations` to minimum that is one of reason why they need to be explicitly registered.
301+
302+
The other reason is the **route order**, because routes are executed in the **order** they are defined.
303+
304+
Having said that, we do offer a service {{modlink "scanner"}} module that automatically register `MVC` routes.
305+
306+
Try it:
307+
308+
http://localhost:8080/mvc/greeting
309+
310+
## adding a name parameter
311+
312+
As we do with script route we are going to add a **required** `name` parameter:
313+
314+
```java
315+
@Path("/greeting")
316+
@GET
317+
public String greeting(String name) {
318+
return "Hello " + name + "!";
319+
}
320+
```
321+
322+
Try it:
323+
324+
http://localhost:8080/mvc/greeting?name=Jooby
325+
326+
To call the service without a name we need to make the `name` parameter an optional parameter:
327+
328+
```java
329+
import java.util.Optional;
330+
...
331+
332+
@Path("/greeting")
333+
@GET
334+
public String greeting(Optional<String> name) {
335+
return "Hello " + name.orElse("World") + "!";
336+
}
337+
```
338+
339+
Try it with a parameter:
340+
341+
http://localhost:8080/mvc/greeting?name=Jooby
342+
343+
Try it without:
344+
345+
http://localhost:8080/mvc/greeting
346+
347+
## path parameter
348+
349+
If you want or prefer a path parameter, you can replace the path pattern with: `/greeting/:name` or allow both of them:
350+
351+
```java
352+
@Path({"/greeting", "/greeting/:name"})
353+
@GET
354+
public String greeting(Optional<String> name) {
355+
return "Hello " + name.orElse("World") + "!";
356+
}
357+
```
358+
359+
Try it with a path parameter:
360+
361+
http://localhost:8080/mvc/greeting/Jooby
362+
363+
Try it with a query parameter:
364+
365+
http://localhost:8080/mvc/greeting?name=Jooby
366+
367+
# conclusion
368+
369+
Your application might looks like something similar to this:
370+
371+
```java
372+
{{source mainclass}}
373+
```
374+
375+
This is an unreal and simple **JSON API** but helps to demonstrate how simple and easy is to build such application in {{jooby}}. **Simplicity** is one of the {{jooby}} goals.
376+
377+
We also demonstrate the **script** and **mvc** programming models, you can pick one or mix both in a single application.
378+
379+
The **script** programming model is perfect for getting thing done quickly and/or for small applications. It is also possible to use the **script** routes on large applications, where you usually split routes in one or more applications and then you compose all those small application into a one.
380+
381+
The **mvc** programming model is a bit more verbose but probably better for large scale applications.
382+
383+
A common pattern for **medium** scale applications is to write the **UI** routes (those who generated HTML) using the **script** programming model while the **Business/API** routes using the **MVC** programming model.
384+
385+
In short, **script** or **mvc** is matter of taste and/or depends on your background.
386+
387+
388+
That's all for now, if you like what you see here please follow us at [@joobyproject](https://twitter.com/joobyproject) and [Github](https://github.com/jooby-project/jooby)
389+
390+
{{> guides/guide.footer}}

0 commit comments

Comments
 (0)