////
Style guidelines:

* Refer to the project in prose as simply Jooby, with no adornment or formatting. Enclose the class
  name `Jooby` in back ticks so readers can distinguish references to the `Jooby` class from 
  references to the Jooby project as a whole.
* 100 characters per line, except when you can't break it up e.g. links or asciidoc directives
* Avoid class definition on Jooby code examples. Always start an example with `{...}`
* Avoid JUnit boilerplate in code examples. Assertions are ok if they complement the example.
* External links should use a caret at the end of the link title e.g.
  link:path/to/doc[the title^] so they open in separate tabs. See
  http://asciidoctor.org/docs/asciidoc-writers-guide/#target-window-and-role-attributes-for-links
* Be funny. Nobody like reading dry documentation.
* Be inclusive: keep usage of male and female names equal in code examples.
* Best edited while drunk

////

= Welcome to Jooby!
Jooby Project <support@jooby.io>
{joobyVersion}

[discrete]
== &infin; do more, more easily

== Introduction

Jooby is a modern, performant and easy to use web framework for Java and Kotlin built on top of your
favorite web server.

[TIP]
====
Latest Release: https://github.com/jooby-project/jooby/releases/tag/v{joobyVersion}[{joobyVersion}].

Looking for previous version? The link:v1[1.x] documentation is still available. 
====

.Welcome!!
[source,java,role="primary"]
----
import io.jooby.Jooby;

public class App extends Jooby {

  {
    get("/", ctx -> "Welcome to Jooby!"); 
  }

  public static void main(String[] args) {
    runApp(args, App::new);
  }
}
----

.Kotlin
[source,kotlin,role="secondary"]
----
import io.jooby.runApp

fun main(args: Array<String>) {
  runApp(args) {
    get ("/") { "Welcome to Jooby!" }
  }
}
----

Source code is available at https://github.com/jooby-project/jooby[GitHub]

=== Features

* Lightweight and Fast. See https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=composite&l=xan9tr-1r[Tech Empower Benchmark]
* Increase productivity with <<hot-reload, Hot-Reload for development>>
* Script/lambda routes using fluent API
* <<mvc-api, MVC routes>> using Jooby or JAX-RS annotations
* link:modules/openapi[OpenAPI 3] supports
* <<execution-model, Event Loop and blocking execution modes>>
* <<responses, Reactive responses>> (Completable Futures, RxJava and Reactor types and Kotlin Coroutines)
* <<server, Multi-server>> including https://www.eclipse.org/jetty[Jetty], https://netty.io[Netty] and http://undertow.io[Undertow]
* Jump to full-stack framework with extension/plugin mechanism and variety of link:modules[]

=== Script API

Script API (a.k.a script routes) provides a fluent DSL, reflection and annotation free based on `lambda` functions.

We usually extend `Jooby` and define routes in the instance initializer:

.Script with sub-class:
[source,java,role="primary"]
----
import io.jooby.Jooby;

public class App extends Jooby {

  {
    get("/", ctx -> "Hello Jooby!"); 
  }

  public static void main(String[] args) {
    runApp(args, App::new);
  }
}
----

.Kotlin
[source,kotlin,role="secondary"]
----
import io.jooby.Kooby;
import io.jooby.runApp;

class App : Kooby({

  get("/") { "Hello Jooby!" }

})

fun main(args: Array<String>) {
  runApp(args, ::App)
}
----

For Java applications we favor extending `Jooby` because DSL looks better (no need
prefix the `get` method with a variable)

This is not strictly necessary (of course), you may prefer to do it without extending `Jooby`:

.Script without subclass:
[source,java,role="primary"]
----
import io.jooby.Jooby;

public class App {

  public static void main(String[] args) {
    runApp(args, app -> {

      app.get("/", ctx -> "Hello Jooby!");

    });
  }
}
----

.Kotlin
[source,kotlin,role="secondary"]
----
import io.jooby.runApp

fun main(args: Array<String>) {
  runApp(args) {

    get("/") { "Hello Jooby!" }

  }
}
----

In case of Kotlin, it doesn't matter which one you choose. DSL looks great with or without extending
`Kooby`.

=== MVC API

The MVC API (a.k.a mvc routes) uses annotation to define routes and byte code generation to execute
them.

.MVC API:
[source,java,role="primary"]
----

import io.jooby.annotations.*;

public class MyController {

  @GET
  public String sayHi() {
    return "Hello Jooby!";
  }
}

public class App {

  public static void main(String[] args) {
    runApp(args, app -> {

      app.use(new MyController());

    });
  }
}
----

.Kotlin
[source,kotlin,role="secondary"]
----
import io.jooby.annotations.*;

class MyController {

  @GET
  fun sayHi() : String {
    return "Hello Jooby!"
  }
}

fun main(args: Array<String>) {
  runApp(args) {

    use(MyController())

  }
}
----

More about MVC and JAX-RS support in the <<mvc-api, MVC API>> chapter.


include::getting-started.adoc[]

include::routing.adoc[]

include::context.adoc[]

include::mvc-api.adoc[]

include::static-files.adoc[]

include::templates.adoc[]

include::session.adoc[]

include::websocket.adoc[]

include::server-sent-event.adoc[]

include::execution-model.adoc[]

include::responses.adoc[]

include::error-handler.adoc[]

include::handlers.adoc[]

include::configuration.adoc[]

include::testing.adoc[]

include::dev-tools.adoc[]

include::packaging/packaging.adoc[]

include::servers.adoc[]

include::extension.adoc[]

include::dependency-injection.adoc[]

include::modules.adoc[]

== Appendix

include::migration.adoc[]
