From 6627cc8fdc93fac3a1de2af4e0463ac6ad3129cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20J=C3=B8rgen=20Hoel?= Date: Mon, 10 Apr 2017 19:43:16 +0200 Subject: [PATCH 1/3] Small language changes --- md/app.md | 6 +++--- md/async.md | 40 +++++++++++++++++++-------------------- md/conf.md | 26 +++++++++++++------------ md/guides/greeting.md | 44 +++++++++++++++++++++---------------------- md/mvc-routes.md | 22 +++++++++++----------- md/philosophy.md | 10 +++++----- 6 files changed, 75 insertions(+), 73 deletions(-) diff --git a/md/app.md b/md/app.md index 948cc1fcb9..0a8f1f408c 100644 --- a/md/app.md +++ b/md/app.md @@ -70,7 +70,7 @@ public class MyModule implements Jooby.Module { } ``` -The `onStart` callbacks are part of bootstrap and executed before server is ready. The `onStarted` callbacks are executed when server is ready. +The `onStart` callbacks are part of bootstrap and executed before the server is ready. The `onStarted` callbacks are executed when the server is ready. Modules are covered later all you need to know now is that you can start/stop module as you usually do from your application. @@ -95,7 +95,7 @@ Callback order is preserved: } ``` -Order is useful for service dependencies, like `ServiceB` should be started after `ServiceA`. +Order is useful for service dependencies, for example if `ServiceB` should be started after `ServiceA`. ### service registry @@ -117,7 +117,7 @@ You have access to the the service registry from start/stop events: ### PostConstruct/PreDestroy annotations -If you prefer the annotation way then: +If you prefer annotations you can do: ```java @Singleton diff --git a/md/async.md b/md/async.md index 647312a256..7642be2c17 100644 --- a/md/async.md +++ b/md/async.md @@ -1,6 +1,6 @@ # thread model -You can see {{jooby}} as an `event loop server` thanks to the supported web servers: {{netty_server}}, {{jetty_server}} and {{undertow_server}}. Being {{netty_server}} the default web server. +You can see {{jooby}} as an `event loop server` thanks to the supported web servers: {{netty_server}}, {{jetty_server}} and {{undertow_server}}. The default web server is {{netty_server}}. {{jooby}} isn't a traditional `thread server` where a HTTP request is bound to a thread. @@ -8,7 +8,7 @@ In {{jooby}} all the HTTP IO operations are performed in async & non blocking fa ## worker threads -The **worker thread** pool is provided by the web server: {{netty_server}}, {{jetty_server}} and {{undertow_server}}. To simplify application programming you can **block a worker thread**, for example you can safely run a **jdbc** query in a **worker thread**: +The **worker thread** pool is provided by one of the supported web servers: {{netty_server}}, {{jetty_server}} or {{undertow_server}}. To simplify application programming you can **block a worker thread**, for example you can safely run a **jdbc** query in a **worker thread**: ```java { @@ -22,11 +22,11 @@ The **worker thread** pool is provided by the web server: {{netty_server}}, {{je } ``` -Here the web server can accept as many connection it can (as its on non blocking) while the worker thread might blocks. +The web server can accept as many connections it can (as its on non blocking) while the worker thread might block. -Default worker thread pool is `20/100`. The correct/right size depends on your **business** and **work load** your application is suppose to handle. We suggest you to start with default setup and see how it goes, later you can reduce or increase the thread pool. +The default worker thread pool is `20/100`. The optimal size depends on the **business** and **work load** your application is suppose to handle. We suggest you to start with the default setup and see how it goes, later you can reduce or increase the thread pool. -In {{jooby}} we favor simplicity over complexity that is why your **code** can block, still there are more advanced setup that allow you to build async and reactive applications. +In {{jooby}} we favor simplicity over complexity that is why your **code** can block, still there are more advanced options that allow you to build async and reactive applications. ## deferred @@ -54,7 +54,7 @@ MVC API: } ``` -Previous examples are just `syntax sugar` for: +The previous examples are just `syntactic sugar` for: ``` return new Deferred(deferred -> { @@ -66,7 +66,7 @@ Previous examples are just `syntax sugar` for: }); ``` -There is more `syntax sugar` if you add the [AsyncMapper]({{defdocs}}/AsyncMapper.html) to your application: +You can get more `syntactic sugar` if you add the [AsyncMapper]({{defdocs}}/AsyncMapper.html) to your application: Script API: @@ -95,9 +95,9 @@ MVC API: } ``` -The [AsyncMapper]({{defdocs}}/AsyncMapper.html) convert `java.util.concurrent.Callable` and `java.util.concurrent.CompletableFuture` objects to {{deferred}} objects. +The [AsyncMapper]({{defdocs}}/AsyncMapper.html) converts `java.util.concurrent.Callable` and `java.util.concurrent.CompletableFuture` objects to {{deferred}} objects. -Another important thing to notice is that the deferred run in the **caller thread** (i.e. worker thread), so by default there is **no context switch** involve while running a {{deferred}} result: +Another important thing to notice is that the deferred run in the **caller thread** (i.e. worker thread), so by default there is **no context switch** involved while running a {{deferred}} result: ```java { @@ -111,7 +111,7 @@ Another important thing to notice is that the deferred run in the **caller threa } ``` -You might first see this as a bad thing, but is actually a good decision, because: +You might see this as a bad thing at first, but it's actually a good decision, because: * It is super easy to setup a default executor (we will see how soon) @@ -119,7 +119,7 @@ You might first see this as a bad thing, but is actually a good decision, becaus ## executor -As we said before, the default executor run in the caller thread (a.k.a direct executor). Let's see how to override the default executor: +As previously mentioned, the default executor runs in the caller thread (a.k.a direct executor). Let's see how to override the default executor: ```java { @@ -131,7 +131,7 @@ As we said before, the default executor run in the caller thread (a.k.a direct e } ``` -Done! Now all our {{deferred}} result run in a `ForkJoinPool`. It also possible to specify an alternative executor: +Done! Now all our {{deferred}} results run in a `ForkJoinPool`. It's also possible to specify an alternative executor: Script API: @@ -175,7 +175,7 @@ import static org.jooby.Deferred.deferred; } ``` -Worth mention the [executor(ExecutorService)]({{defdocs}}/Jooby.html#executor-java.util.concurrent.ExecutorService-) methods automatically `shutdown` at application shutdown time. +It's worth mentioning that the [executor(ExecutorService)]({{defdocs}}/Jooby.html#executor-java.util.concurrent.ExecutorService-) methods automatically `shutdown` at application shutdown time. ## promise @@ -216,7 +216,7 @@ MVC API: } ``` -The **"promise"** version of {{deferred}} object is a key concept for integrating with external libraries. +The **"promise"** version of the {{deferred}} object is a key concept for integrating with external libraries. ## advanced configuration @@ -226,7 +226,7 @@ Suppose you want to build a truly async application and after a **deep analysis* * Call a remote service * Make a CPU intensive computation -These are the 3 points where your application is suppose to block and wait for a result. +These are the 3 points where your application is supposed to block and wait for a result. Let's start by reducing the **worker thread pool** to the number of **available processors**: @@ -247,9 +247,9 @@ Let's create a custom thread pool for each blocking access: } ``` -For `database` access, we use a `cached` executor that will grow without a limit but free and release thread that are idle after `60s`. +For `database` access, we use a `cached` executor that will grow without a limit but free and release threads that are idle after `60s`. -For `remote` service, we use a `fixed` executor of `32` thread. The number here: `32` is just a random number for the purpose of the example. +For `remote` service, we use a `fixed` executor of `32` threads. The number here: `32` is just a random number for the purpose of the example. For `intensive` computation, we use a `single` thread executor. Computation is too expensive and we want **one and only one** running at any time. @@ -314,7 +314,7 @@ Here is the same example with [rx java](https://github.com/ReactiveX/RxJava): } ``` -Main difference are: +The main differences are: * we keep the default executor: `direct`. So we don't create a new thread and avoid context switching. * we use {{deferred}} object as `promise` and integrate with [rx java](https://github.com/ReactiveX/RxJava). @@ -322,6 +322,6 @@ Main difference are: This is just one more example to demonstrate the value of the {{deferred}} object, because we provide an [rxjava](/doc/rxjava) module which takes care of binding {{deferred}} object into `Observables`. -That's all about {{deferred}} object, it allows you to build async and reactive applications and at the same time: **keep it simple** (Jooby design goal). +That sums up everything about the {{deferred}} object. It allows you to build async and reactive applications and at the same time: **keep it simple** (a Jooby design goal). -Also, we invite you to checkout the available [async/reactive modules](/doc/async). +You're also invited to check out the available [async/reactive modules](/doc/async). diff --git a/md/conf.md b/md/conf.md index 144a47525f..cc588af2a4 100644 --- a/md/conf.md +++ b/md/conf.md @@ -1,8 +1,8 @@ # conf, env and logging -Jooby delegates configuration management to [Config library](https://github.com/typesafehub/config). +Jooby delegates configuration management to the [Config library](https://github.com/typesafehub/config). -By defaults Jooby expects to find an ```application.conf``` file at the root of classpath. You can find the `.conf` file under `conf` classpath directory. +By defaults Jooby expects to find an ```application.conf``` file at the root of classpath. You can find the `.conf` file under the `conf` classpath directory. ## getting properties @@ -59,7 +59,7 @@ Automatic type conversion is provided when a type: 6) Has a static method **forName** that accepts a single **String** argument. Like ```java.nio.charset.Charset``` -You're free to inject the entirely ```com.typesafe.config.Config``` object or `sub-path/tree` of it. +You're free to inject the entire ```com.typesafe.config.Config``` object or `sub-path/tree` of it. ## environment @@ -69,7 +69,7 @@ This special property is represented at runtime with the [Env]({{apidocs}}/org/j For example: a module might decided to create a connection pool, cache, etc when ```application.env``` isn't set to `dev`. -The `application.env` property can be set as command line argument too: +The `application.env` property can be set as command line argument as well: Using a `fat jar`: @@ -80,9 +80,9 @@ Using [stork](/doc/stork): bin/myapp --start prod -## turn on/off features +## turning features on or off -As described before the ```application.env``` property defines the environment where the application is being executed. It is possible to turn on/off specific features base on the application environment: +As described before, the ```application.env``` property defines the environment where the application is being executed. It's possible to turn on/off specific features based on the application environment: ```java { @@ -108,7 +108,7 @@ There is a `~` (complement) operator: } ``` -The ```environment callback``` has access to ```config``` object, see: +The ```environment callback``` has access to the ```config``` object, see: ```java { @@ -141,7 +141,7 @@ Here is the list of special properties available in Jooby: ## precedence -Configuration files are loaded in the following order (first-listed are higher priority) +Configuration files are loaded in the following order: * system properties * arguments properties @@ -150,6 +150,8 @@ Configuration files are loaded in the following order (first-listed are higher p * ([application].[conf])? * [module].[conf]* +The first occurence of a property will take precedence. + ### system properties System properties can override any other property. A system property is set at startup time, like: @@ -188,7 +190,7 @@ The default `classpath conf` file: `application.conf` ### [module].[conf] -A [Module]({{defdocs}}/Jooby.Module.html) might have define his own set of (default) properties via [Module.config]({{defdocs}}/Jooby.Module.html#config--) method. +A [Module]({{defdocs}}/Jooby.Module.html) might have defined its own set of (default) properties via the [Module.config]({{defdocs}}/Jooby.Module.html#config--) method. ```java { @@ -198,7 +200,7 @@ A [Module]({{defdocs}}/Jooby.Module.html) might have define his own set of (defa ### custom .conf -As we said before, the default `conf` file is `application.conf`, but you can use any other name you want: +As mentioned earlier, the default `conf` file is `application.conf`, but you can use whatever name you prefer: ```java { @@ -228,7 +230,7 @@ As we said before, the default `conf` file is `application.conf`, but you can us } ``` -* Starting the application in `dev` produces `conf` tree similar to: +* Starting the application in `dev` produces a `conf` tree similar to: ``` . @@ -241,7 +243,7 @@ As we said before, the default `conf` file is `application.conf`, but you can us └── ... ``` -* Starting the application in `prod` produces `conf` tree similar to: +* Starting the application in `prod` produces a `conf` tree similar to: ``` . diff --git a/md/guides/greeting.md b/md/guides/greeting.md index e97b666a9d..7f45c205fa 100644 --- a/md/guides/greeting.md +++ b/md/guides/greeting.md @@ -9,7 +9,7 @@ The service will be available at: http://localhost:8080/greeting ``` -and respond with `JSON` response: +and respond with the `JSON` response: ```json { @@ -18,16 +18,16 @@ and respond with `JSON` response: } ``` -{{jooby}} offers two programming model: +{{jooby}} offers two programming models: -* **script**, where routes are writing via **DSL** and lambdas. -* **mvc**, where routes are writing as class method and annotations. +* **script**, where routes are written via **DSL** and lambdas. +* **mvc**, where routes are written as class method and annotations. In this guide you will learn how to write a simple **JSON API** using both models. # requirements -Make sure you have all these software installed it in your computer: +Make sure you have the following installed on your computer: * A text editor or IDE * {{java}} or later @@ -41,7 +41,7 @@ Open a terminal/console and paste: mvn archetype:generate -B -DgroupId={{pkgguide}} -DartifactId={{guide}} -Dversion=1.0 -DarchetypeArtifactId=jooby-archetype -DarchetypeGroupId=org.jooby -DarchetypeVersion={{version}} ``` -A simple `hello world` application is ready to run. Try now: +A simple `hello world` application is now ready to run. Try: ``` cd {{guide}} @@ -55,11 +55,11 @@ Open a browser and type: http://localhost:8080 ``` -> **TIP**: If you make a change `jooby:run` automatically restart and reload your application. More at {{link "/doc/devtools" "development tools"}}. +> **TIP**: If you make a change, `jooby:run` will automatically restart and reload your application. More at {{link "/doc/devtools" "development tools"}}. # quick preview -Before moving forward let's have a look at `App.java`: +Before moving forward, let's have a look at `App.java`: ```java package {{guide}}; @@ -81,11 +81,11 @@ public class App extends Jooby { // 1 extends Jooby } ``` -That's all you need to get up and running a simple **Hello World** {{javadoc "Jooby"}} application. +That's all you need to get a simple **Hello World** {{javadoc "Jooby"}} application up and running. # script route -Now we already see how a {{javadoc "Jooby"}} application looks like, we are going to create a simple greeting **JSON API**: +Now that we've seen what a {{javadoc "Jooby"}} application looks like, we are going to create a simple greeting **JSON API**: First `Greeting.java`: @@ -109,11 +109,11 @@ Try it: http://localhost:8080/greeting ``` -You'll see `Hello World!` in your browser, not bad ugh? +You'll see `Hello World!` in your browser, not bad huh? Not bad at all! But if you look closely we send a `text/html` response not an `application/json` response. -Before building **JSON** response let's see how to read a HTTP parameter. +Before building **JSON** response let's see how to read an HTTP parameter. ## adding a name parameter @@ -131,7 +131,7 @@ We are going to improve our service by allowing a name parameter: } ``` -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. +HTTP parameters are accessible via the {{javadoc "Request" "param" "java.lang.String"}} method, that is why we change our route a bit to access the {{javadoc "Request"}} object. Try it: @@ -199,11 +199,11 @@ Try it with a query parameter: http://localhost:8080/greeting?name=Jooby ``` -Nice ugh? +Nice huh? # json -{{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"}}. +{{jooby}} is a micro-web framework, so in order to write a **JSON** response we need one of the available {{link "/doc/parser-and-renderer" "json modules"}}. Here we will use {{modlink "jackson"}} but keep in mind the process is exactly the same if you choose any other module. @@ -219,7 +219,7 @@ Let's add the {{modlink "jackson"}} dependency to your project: ``` -If `jooby:run` is running, please restart it. We need to force a restart due we added a new dependency. +If `jooby:run` is running, please restart it. We need to force a restart due to having added a new dependency. ## use @@ -283,7 +283,7 @@ public class Greetings { } ``` -The **MVC** programming model is similar to {{spring}} and/or {{jersey}}, except a `MVC` routes must be registered at at application startup time. +The **MVC** programming model is similar to {{spring}} and/or {{jersey}}, except an `MVC` route must be registered at application startup time. ## registering a mvc route @@ -301,7 +301,7 @@ We try to keep `reflection`, `classpath scanning` and `annotations` to minimum t The other reason is the **route order**, because routes are executed in the **order** they are defined. -Having said that, we do offer a service {{modlink "scanner"}} module that automatically register `MVC` routes. +Having said that, we do offer a service {{modlink "scanner"}} module that automatically registers `MVC` routes. Try it: @@ -309,7 +309,7 @@ Try it: ## adding a name parameter -As we do with script route we are going to add a **required** `name` parameter: +As we did with the script route, we are going to add a **required** `name` parameter: ```java @Path("/greeting") @@ -366,13 +366,13 @@ Try it with a query parameter: # conclusion -Your application might looks like something similar to this: +Your application might look something like this now: ```java {{source mainclass}} ``` -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. +This is an unrealistic **JSON API**, but it helps to demonstrate how simple and easy is to build such an application in {{jooby}}. **Simplicity** is one of the {{jooby}} goals. We also demonstrate the **script** and **mvc** programming models, you can pick one or mix both in a single application. @@ -380,7 +380,7 @@ The **script** programming model is perfect for getting thing done quickly and/o The **mvc** programming model is a bit more verbose but probably better for large scale applications. -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. +A common pattern for **medium** scale applications is to write the **UI** routes (those which generate HTML) using the **script** programming model while writing the **Business/API** routes using the **MVC** programming model. In short, **script** or **mvc** is matter of taste and/or depends on your background. diff --git a/md/mvc-routes.md b/md/mvc-routes.md index 4e26013319..2907f745db 100644 --- a/md/mvc-routes.md +++ b/md/mvc-routes.md @@ -15,9 +15,9 @@ public class MyRoutes { Annotations are identical to [Jersey/JAX-RS](https://jersey.java.net/) and they can be found under the package `org.jooby.mvc`. -> **NOTE**: Jooby doesn't implement the **JAX-RS** specification that is why it has his own version of the annotations. +> **NOTE**: Jooby doesn't implement the **JAX-RS** specification that is why it has its own version of the annotations. -A mvc route can be injected by {{guice}}: +An mvc route can be injected by {{guice}}: ```java @Path("/") @@ -85,20 +85,20 @@ public class MyRoutes { } ``` -### registering a mvc route +### registering an mvc route Mvc routes must be registered, there is **no auto-discover** feature, no classpath scanning, ..., etc. -The order in which you define your routes has a huge importance and it defines how your app will work. +The order in which you define your routes is very important and it defines how your app will work. This is one of the reason why mvc routes need to be explicitly registered. -The other reason is bootstrap time, declaring the route explicitly helps to reduce bootstrap time. +The other reason is that declaring the route explicitly helps to reduce bootstrap time. -So, how do I register a mvc route? +So, how do I register an mvc route? -In the same way everything else is registered in {{jooby}} from your application class: +In the same way everything else is registered in {{jooby}}, from your application class: ```java public class App extends Jooby { @@ -177,7 +177,7 @@ Same for {{file_upload}} } ``` -Jooby uses the method parameter name and bind that name to a request parameter. If you want explicit mapping and/or the request parameter isn't a valid Java identifier: +Jooby uses the method parameter name and binds that name to a request parameter. If you want an explicit mapping and/or the request parameter isn't a valid Java identifier: ```java @GET @@ -188,7 +188,7 @@ Jooby uses the method parameter name and bind that name to a request parameter. ### form submit -Form submitted as {{formurlencoded}} or {{formmultipart}} don't require anything: +A form submitted as {{formurlencoded}} or {{formmultipart}} doesn't require anything: ```java @POST @@ -199,7 +199,7 @@ Form submitted as {{formurlencoded}} or {{formmultipart}} don't require anything ### request body -Annotated the method parameter with [@Body](/apidocs/org/jooby/mvc/Body.html) annotation: +Annotate the method parameter with the [@Body](/apidocs/org/jooby/mvc/Body.html) annotation: ```java @POST @@ -211,7 +211,7 @@ Annotated the method parameter with [@Body](/apidocs/org/jooby/mvc/Body.html) an ### request headers -Annotated the method parameter with [@Header]({{defdocs}}/mvc/Header.html) annotation: +Annotate the method parameter with the [@Header]({{defdocs}}/mvc/Header.html) annotation: ```java @GET diff --git a/md/philosophy.md b/md/philosophy.md index a4c6e4eac7..c3a0f49a35 100644 --- a/md/philosophy.md +++ b/md/philosophy.md @@ -1,10 +1,10 @@ # do more, more easily - **Simple** and **effective** programming model for building small and large scale web applications -- Build with **developer productive** in mind +- Built with **developer productivity** in mind - Plain **Java DSL** for routes (no xml, or similar) -- **Reflection**, **annotations** and **dependency injection** are keep to **minimum** and in some cases it is completely optional -- **No classpath hell**, default deployment model uses a normal JVM bootstrap -- Modules are easy to use and do as less as possible +- **Reflection**, **annotations** and **dependency injection** are kept to a **minimum** and in some cases is completely optional +- **No classpath hell**, the default deployment model uses a normal JVM bootstrap +- Modules are easy to use and do as little as possible -{{jooby}} keeps it **simple** but yet **powerful**. +{{jooby}} keeps it **simple** yet **powerful**. From 4672798c0f04cd56934ae9ba3d602c4d75373649 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20J=C3=B8rgen=20Hoel?= Date: Wed, 12 Apr 2017 09:48:08 +0200 Subject: [PATCH 2/3] More language changes for docs --- md/asset-processor.md | 31 +++---- md/assets-require.md | 2 +- md/async.md | 32 ++++---- md/available-modules.md | 12 +-- md/capsule.md | 2 +- md/conf.md | 6 +- md/cors.md | 4 +- md/doc/caches/caches.md | 14 ++-- md/doc/datastore/datastore.md | 4 +- md/doc/hbs/hbs.md | 6 +- .../parser-and-renderer.md | 8 +- md/doc/querydsl-jpa/querydsl-jpa.md | 10 +-- md/doc/security/security.md | 2 +- md/doc/session/session.md | 4 +- md/docker.md | 8 +- md/dynamic-routing.md | 4 +- md/err.md | 30 +++---- md/faq.md | 6 +- md/fatjar.md | 8 +- md/gradle-jooby-run.md | 14 ++-- md/guides/deployment.md | 27 +++---- md/guides/greeting.md | 20 ++--- md/h2.md | 10 +-- md/https.md | 2 +- md/interceptors.md | 24 +++--- md/javascript.md | 18 ++--- md/jooby-pre.md | 2 +- md/kotlin.md | 16 ++-- md/logging.md | 2 +- md/modules.md | 18 ++--- md/mvc-routes.md | 16 ++-- md/quickstart.md | 20 ++--- md/req.md | 80 +++++++++---------- md/route-attrs.md | 24 +++--- md/routes.md | 79 +++++++++--------- md/rsp.md | 20 ++--- md/session.md | 28 +++---- md/spec.md | 52 ++++++------ md/sse.md | 22 ++--- md/stork.md | 2 +- md/tests.md | 32 ++++---- md/war.md | 22 ++--- md/web-sockets.md | 28 +++---- md/working-with-data.md | 40 +++++----- md/xss.md | 16 ++-- 45 files changed, 413 insertions(+), 414 deletions(-) diff --git a/md/asset-processor.md b/md/asset-processor.md index 9191bfe58d..f7f4e58090 100644 --- a/md/asset-processor.md +++ b/md/asset-processor.md @@ -1,10 +1,10 @@ # asset processor -Checks, validate and/or modify asset contents. An [AssetProcessor]({{defdocs}}/assets/AssetProcessor.html) is usually provided as a separated dependency. +Checks, validates and/or modifies asset contents. An [AssetProcessor]({{defdocs}}/assets/AssetProcessor.html) is usually provided as a separate dependency. -## how to use it? +## usage -First thing to do is to add the dependency: +Start by adding the dependency to your ```pom.xml```: ```xml @@ -14,9 +14,10 @@ First thing to do is to add the dependency: ``` -Did you see the **provided** scope? We just need the processor for development, because assets are processed at runtime. In ```prod```, assets are processed at built-time via Maven/Gradle plugin, so we don't need this library/dependency. This also, helps to keep our dependencies and the jar size small. +Notice the **provided** scope. The processor is only required for development, since the assets are processed at runtime in this case. In ```prod```, assets are processed at build-time via the Maven or Gradle plugins, so the dependency is not needed there. This also helps to keep the number of dependencies and the jar size smaller. + +After the dependency is declared, all that's needed is to add the processor to the pipeline: -Now we have the dependency all we have to do is to add it to our pipeline: ```text assets { @@ -28,7 +29,7 @@ assets { ## configuration -It is possible to configure or set options too: +It's possible to configure or set options as well: ```text assets { @@ -42,7 +43,7 @@ assets { } ``` -Previous example, set a ```foo``` property to ```bar```! Options can be set per environment too: +The previous example sets the ```foo``` property to ```bar```. Options can be set per environment as well: ```text assets { @@ -62,11 +63,11 @@ assets { } ``` -Here, in ```dev``` processor has two properties: ```foo:foo``` and ```bar:bar```, while in ```dist``` the processor only has ```foo:bar``` +In this example, the processor will have two properties in the ```dev``` environment: ```foo:foo``` and ```bar:bar```, while in ```dist``` the processor will only have ```foo:bar``` ## binding -The ```my-processor``` will be resolved it to: ```org.jooby.assets.MyProcessor``` class. The processor name is converted to ```MyProcessor```, it converts the hyphenated name to upper camel and by default processors are defined in the ```org.jooby.assets``` package. +The ```my-processor``` token will be resolved to the: ```org.jooby.assets.MyProcessor``` class. The processor name is converted to ```MyProcessor``` by converting the hyphenated name to upper camel case and by placing it in the ```org.jooby.assets``` package (a default for processors). A custom binding is provided via the ```class``` property: @@ -86,9 +87,9 @@ assets { Contributes new or dynamically generated content to a ```fileset```. Content generated by an aggregator might be processed by an {@link AssetProcessor}. -## how to use it? +## usage -First thing to do is to add the dependency: +Start by adding the dependency to your ```pom.xml```: ```xml @@ -99,9 +100,9 @@ First thing to do is to add the dependency: ``` -Did you see the **provided** scope? We just need the aggregator for development, because assets are processed at runtime. In ```prod```, assets are processed at built-time via Maven/Gradle plugin, so we don't need it. This also, helps to keep our dependencies and the jar size small. +Notice the **provided** scope. The aggregator is only required for development, since the assets are processed at runtime in this case. In ```prod```, assets are processed at build-time via the Maven or Gradle plugins, so the dependency is not needed there. This also helps to keep the number of dependencies and the jar size smaller. -Now we have the dependency all we have to do is to add the ```svg-sprites``` aggregator to a fileset: +After the dependency is declared, all that's needed is to add the ```svg-sprites``` aggregator to a fileset: ``` assets { @@ -124,7 +125,7 @@ assets { } ``` -Here for example, the ```svg-sprites``` aggregator contributes the ```css/sprite.css``` file to the ```home``` fileset. The fileset then looks like: +In this example, the ```svg-sprites``` aggregator contributes the ```css/sprite.css``` file to the ```home``` fileset. The fileset then looks like: ``` assets { @@ -138,7 +139,7 @@ assets { } ``` -It replaces the aggregator name with one or more files from [AssetAggregator.fileset]({{defdocs}}/assets/AssetAggregator.html#fileset--) method. +It replaces the aggregator name with one or more files from the [AssetAggregator.fileset]({{defdocs}}/assets/AssetAggregator.html#fileset--) method. # available processors diff --git a/md/assets-require.md b/md/assets-require.md index d2e4234090..a7c7ca6fda 100644 --- a/md/assets-require.md +++ b/md/assets-require.md @@ -1 +1 @@ -Make sure you already setup the [assets module](https://github.com/jooby-project/jooby/tree/master/jooby-assets) in your project! +Make sure you've already set up the [assets module](https://github.com/jooby-project/jooby/tree/master/jooby-assets) in your project! diff --git a/md/async.md b/md/async.md index 7642be2c17..f9cec2b47e 100644 --- a/md/async.md +++ b/md/async.md @@ -24,9 +24,9 @@ The **worker thread** pool is provided by one of the supported web servers: {{ne The web server can accept as many connections it can (as its on non blocking) while the worker thread might block. -The default worker thread pool is `20/100`. The optimal size depends on the **business** and **work load** your application is suppose to handle. We suggest you to start with the default setup and see how it goes, later you can reduce or increase the thread pool. +The default worker thread pool is `20/100`. The optimal size depends on the **business** and **work load** your application is supposed to handle. It's recommended to start with the default setup and then tune the size of the thread pool if the need arises. -In {{jooby}} we favor simplicity over complexity that is why your **code** can block, still there are more advanced options that allow you to build async and reactive applications. +{{jooby}} favors simplicity over complexity hence allowing your **code** to block. However, it also provides you with more advanced options that will allow you to build async and reactive applications. ## deferred @@ -97,7 +97,7 @@ MVC API: The [AsyncMapper]({{defdocs}}/AsyncMapper.html) converts `java.util.concurrent.Callable` and `java.util.concurrent.CompletableFuture` objects to {{deferred}} objects. -Another important thing to notice is that the deferred run in the **caller thread** (i.e. worker thread), so by default there is **no context switch** involved while running a {{deferred}} result: +Another important thing to notice is that the deferred will run in the **caller thread** (i.e. worker thread), so by default there is **no context switch** involved in obtaining a {{deferred}} result: ```java { @@ -111,11 +111,11 @@ Another important thing to notice is that the deferred run in the **caller threa } ``` -You might see this as a bad thing at first, but it's actually a good decision, because: +This might not seem optimal at first, but there are some benefits to this: -* It is super easy to setup a default executor (we will see how soon) +* It makes it very easy to set up a default executor (this will be explained shortly) -* Provides better integration with async & reactive libraries. A `direct` executor avoid the need of switching to a new thread and then probably dispatch (again) to a different thread provided by a library. +* It provides better integration with async & reactive libraries. A `direct` executor avoids the need of switching to a new thread and then probably dispatch (again) to a different thread provided by a library. ## executor @@ -220,7 +220,7 @@ The **"promise"** version of the {{deferred}} object is a key concept for integr ## advanced configuration -Suppose you want to build a truly async application and after a **deep analysis** of your business you realize your application need to: +Suppose you want to build a truly async application and after a **deep analysis** of your business demands you realize your application needs to: * Access a database * Call a remote service @@ -235,7 +235,7 @@ server.threads.Min = ${runtime.processors} server.threads.Max = ${runtime.processors} ``` -With this change, you need to be careful and **don't run blocking code** on routes anymore. Otherwise performance will be affected. +With this change, you need to be careful to **avoid any blocking code** on routes, otherwise performance will suffer. Let's create a custom thread pool for each blocking access: @@ -247,11 +247,11 @@ Let's create a custom thread pool for each blocking access: } ``` -For `database` access, we use a `cached` executor that will grow without a limit but free and release threads that are idle after `60s`. +For `database` access, we use a `cached` executor which will grow without a limit but free and release threads that are idle after `60s`. -For `remote` service, we use a `fixed` executor of `32` threads. The number here: `32` is just a random number for the purpose of the example. +For `remote` service, we use a `fixed` executor of `32` threads. The number `32` is just a random number for the purpose of the example. -For `intensive` computation, we use a `single` thread executor. Computation is too expensive and we want **one and only one** running at any time. +For `intensive` computations, we use a `single` thread executor. Computation is too expensive and we want **one and only one** running at any time. ```java { @@ -277,7 +277,7 @@ For `intensive` computation, we use a `single` thread executor. Computation is t } ``` -Here is the same example with [rx java](https://github.com/ReactiveX/RxJava): +Here's the same example with [rx java](https://github.com/ReactiveX/RxJava): ```java { @@ -316,11 +316,11 @@ Here is the same example with [rx java](https://github.com/ReactiveX/RxJava): The main differences are: -* we keep the default executor: `direct`. So we don't create a new thread and avoid context switching. -* we use {{deferred}} object as `promise` and integrate with [rx java](https://github.com/ReactiveX/RxJava). -* different thread pool semantic is done via [rx schedulers](http://reactivex.io/documentation/scheduler.html). +* the default executor is kept `direct`. No new thread is created and context switching is avoided. +* the {{deferred}} object is used as a `promise` and integrate with [rx java](https://github.com/ReactiveX/RxJava). +* different thread pool semantics is achieved with the help of [rx schedulers](http://reactivex.io/documentation/scheduler.html). -This is just one more example to demonstrate the value of the {{deferred}} object, because we provide an [rxjava](/doc/rxjava) module which takes care of binding {{deferred}} object into `Observables`. +This is just another example to demonstrate the value of the {{deferred}} object, since a [rxjava](/doc/rxjava) module is provided which takes care of binding the {{deferred}} object into `Observables`. That sums up everything about the {{deferred}} object. It allows you to build async and reactive applications and at the same time: **keep it simple** (a Jooby design goal). diff --git a/md/available-modules.md b/md/available-modules.md index fe52a5e935..df5dfe6f4e 100644 --- a/md/available-modules.md +++ b/md/available-modules.md @@ -9,15 +9,15 @@ * [gson](https://github.com/jooby-project/jooby/tree/master/jooby-gson): JSON supports via Gson. ## template engines -* [handlebars/mustache](https://github.com/jooby-project/jooby/tree/master/jooby-hbs): logic less and semantic Mustache templates. +* [handlebars/mustache](https://github.com/jooby-project/jooby/tree/master/jooby-hbs): logic-less and semantic Mustache templates. * [freemarker](https://github.com/jooby-project/jooby/tree/master/jooby-ftl): render templates with FreeMarker. ## session -* [redis](https://github.com/jooby-project/jooby/tree/master/jooby-jedis/#redis-session-store): HTTP session on {{redis}}. -* [memcached](https://github.com/jooby-project/jooby/tree/master/jooby-spymemcached/#session-store): HTTP session on {{memcached}}. -* [mongodb](https://github.com/jooby-project/jooby/tree/master/jooby-mongodb/#mongodb-session-store): HTTP session on {{mongodb}}. -* [hazelcast](https://github.com/jooby-project/jooby/tree/master/jooby-hazelcast/#session-store): HTTP session on {{hazelcast}}. -* [ehcache](https://github.com/jooby-project/jooby/tree/master/jooby-ehcache/#session-store): HTTP session on {{ehcache}}. +* [redis](https://github.com/jooby-project/jooby/tree/master/jooby-jedis/#redis-session-store): HTTP session store for {{redis}}. +* [memcached](https://github.com/jooby-project/jooby/tree/master/jooby-spymemcached/#session-store): HTTP session store for {{memcached}}. +* [mongodb](https://github.com/jooby-project/jooby/tree/master/jooby-mongodb/#mongodb-session-store): HTTP session store for {{mongodb}}. +* [hazelcast](https://github.com/jooby-project/jooby/tree/master/jooby-hazelcast/#session-store): HTTP session store for {{hazelcast}}. +* [ehcache](https://github.com/jooby-project/jooby/tree/master/jooby-ehcache/#session-store): HTTP session store for {{ehcache}}. ## sql * [jdbc](https://github.com/jooby-project/jooby/tree/master/jooby-jdbc): high performance connection pool for jdbc via {{hikari}}. diff --git a/md/capsule.md b/md/capsule.md index 195a2b539e..645ea74885 100644 --- a/md/capsule.md +++ b/md/capsule.md @@ -24,7 +24,7 @@ The ```capsule``` Maven profile is activated by the presence of the ```src/etc/c ## options -Integration provides some defaults, which are listed here: +The integration provides the following defaults: ```xml diff --git a/md/conf.md b/md/conf.md index cc588af2a4..33d0228cd1 100644 --- a/md/conf.md +++ b/md/conf.md @@ -2,7 +2,7 @@ Jooby delegates configuration management to the [Config library](https://github.com/typesafehub/config). -By defaults Jooby expects to find an ```application.conf``` file at the root of classpath. You can find the `.conf` file under the `conf` classpath directory. +By default, Jooby expects to find an ```application.conf``` file at the root of the classpath. You can find the `.conf` file under the `conf` classpath directory. ## getting properties @@ -63,11 +63,11 @@ You're free to inject the entire ```com.typesafe.config.Config``` object or `sub ## environment -Jooby internals and the module system rely on the ```application.env``` property. By defaults, this property is set to: ```dev```. +Jooby internals and the module system rely on the ```application.env``` property. By default, this property is set to: ```dev```. This special property is represented at runtime with the [Env]({{apidocs}}/org/jooby/Env.html) class. -For example: a module might decided to create a connection pool, cache, etc when ```application.env``` isn't set to `dev`. +For example: a module might decided to create a connection pool, cache, etc. when ```application.env``` isn't set to `dev`. The `application.env` property can be set as command line argument as well: diff --git a/md/cors.md b/md/cors.md index 8aae01df2a..ca0d6070ab 100644 --- a/md/cors.md +++ b/md/cors.md @@ -1,6 +1,6 @@ ## cors -Cross-origin resource sharing (CORS) is a mechanism that allows restricted resources +Cross-origin resource sharing ([CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS)) is a mechanism that allows restricted resources (e.g. fonts, JavaScript, etc.) on a web page to be requested from another domain outside the domain from which the resource originated. ### usage @@ -62,5 +62,5 @@ cors { } ``` -```CORS``` options are represented at runtime by [Cors]({{defdocs}}/handlers/Cors.html). +```CORS``` options are represented at runtime by the [Cors]({{defdocs}}/handlers/Cors.html) handler. diff --git a/md/doc/caches/caches.md b/md/doc/caches/caches.md index 50d0b5291d..82e47c5654 100644 --- a/md/doc/caches/caches.md +++ b/md/doc/caches/caches.md @@ -1,24 +1,24 @@ # caches -Find here access to various caches solutions including {{redis}}, {{memcached}}, etc..., but also pure Java solutions like {{hazelcast}} or {{ehcache}}. +These modules provide access to various cache solutions including {{redis}}, {{memcached}}, etc., as well as to pure Java solutions like {{hazelcast}} and {{ehcache}}. ## redis -[Jedis](/doc/jedis) provides access to a {{redis}} cache via {{jedis}} driver. +[Jedis](/doc/jedis) provides access to a {{redis}} cache via the {{jedis}} driver. ## memcached -[Spymemcached](/doc/spymemcached) provides access to a {{memcached}} cache via {{spymemcached}} driver. +[Spymemcached](/doc/spymemcached) provides access to a {{memcached}} cache via the {{spymemcached}} driver. ## caffeine -[Caffeine](/doc/caffeine): [Caffeine](https://github.com/ben-manes/caffeine) caches. +[Caffeine](/doc/caffeine): [Caffeine](https://github.com/ben-manes/caffeine) cache support. ## ehcache -[Ehcache](/doc/ehcache): {{ehcache}} caches. +[Ehcache](/doc/ehcache): {{ehcache}} support. ## guava -[Guava](/doc/guava-cache): [Guava](https://github.com/google/guava) caches. +[Guava](/doc/guava-cache): [Guava](https://github.com/google/guava) cache support. ## hazelcast -[Hazelcast](/doc/hazelcast): {{hazelcast}} caches. +[Hazelcast](/doc/hazelcast): {{hazelcast}} cache support. diff --git a/md/doc/datastore/datastore.md b/md/doc/datastore/datastore.md index ddae35172e..ff765b1deb 100644 --- a/md/doc/datastore/datastore.md +++ b/md/doc/datastore/datastore.md @@ -1,6 +1,6 @@ # data store -Find access to various data store including relational, documented oriented, key/value, etc. +These are modules providing access to various data stores, including relational, document oriented, key/value stores, etc. # jdbc @@ -32,7 +32,7 @@ The [querydsl-jpa](/doc/querydsl-jpa) provides unified Queries for JPA. [Queryds ## requery -[Requery](/doc/requery) a light but powerful object mapping and SQL generator for Java/Kotlin/Android with RxJava and Java 8 support. Easily map to or create databases, perform queries and updates from any platform that uses Java. +[Requery](/doc/requery) is a light but powerful object mapping and SQL generator for Java/Kotlin/Android with RxJava and Java 8 support. Easily map to or create databases, perform queries and updates from any platform that uses Java. ## rxjdbc diff --git a/md/doc/hbs/hbs.md b/md/doc/hbs/hbs.md index 895008b389..e96a7b7b1a 100644 --- a/md/doc/hbs/hbs.md +++ b/md/doc/hbs/hbs.md @@ -1,6 +1,6 @@ # handlebars -Logic less and semantic templates via {{handlebars}}. +Logic-less and semantic templates via [Handlebars.java](https://github.com/jknack/handlebars.java). ## exports @@ -33,7 +33,7 @@ public/index.html: {{model}} ``` -Templates are loaded from root of classpath: ```/``` and must end with: ```.html``` file extension. +Templates are loaded from the root of the classpath: ```/``` and must end with: ```.html``` file extension. ## request locals @@ -94,7 +94,7 @@ Templates are loaded from the root of classpath and must end with ```.html```. Y Cache is OFF when ```env=dev``` (useful for template reloading), otherwise is ON. -Cache is backed by [Guava](https://github.com/google/guava) and the default cache will expire after ```100``` entries. +The cache is backed by [Guava](https://github.com/google/guava) and the default cache will expire after ```100``` entries. If ```100``` entries is not enough or you need a more advanced cache setting, just set the ```hbs.cache``` option: diff --git a/md/doc/parser-and-renderer/parser-and-renderer.md b/md/doc/parser-and-renderer/parser-and-renderer.md index b4c9154c60..57422e5a0f 100644 --- a/md/doc/parser-and-renderer/parser-and-renderer.md +++ b/md/doc/parser-and-renderer/parser-and-renderer.md @@ -1,6 +1,6 @@ # parser and renderer -Find here the available modules for parsing or rendering several formats. +Jooby includes modules for rendering with many common template engines. # template engines @@ -14,7 +14,7 @@ Find here the available modules for parsing or rendering several formats. ## handlebars -[Handlebars](/doc/hbs) logic less and semantic templates via {{handlebars}}. +[Handlebars](/doc/hbs) logic-less and semantic templates via [Handlebars.java](https://github.com/jknack/handlebars.java). ## pebble @@ -32,8 +32,8 @@ Find here the available modules for parsing or rendering several formats. ## jackson -JSON supports via [jackson](/doc/jackson). +JSON support via [jackson](/doc/jackson). ## gson -JSON supports via [gson](/doc/gson). +JSON support via [gson](/doc/gson). diff --git a/md/doc/querydsl-jpa/querydsl-jpa.md b/md/doc/querydsl-jpa/querydsl-jpa.md index a6396bcd47..058b06f943 100644 --- a/md/doc/querydsl-jpa/querydsl-jpa.md +++ b/md/doc/querydsl-jpa/querydsl-jpa.md @@ -4,11 +4,11 @@ This module provides [JPA](http://www.querydsl.com/static/querydsl/4.0.9/reference/html_single/#jpa_integration) integration. -> NOTE: this module doesn't provide JPA support to your application. Checkout the [hbm module](/doc/hbm) for JPA supports. +> NOTE: this module doesn't provide JPA support to your application. Check out the [hbm module](/doc/hbm) for JPA support. ## usage -* Write a ```querydsl-jpa.activator``` file inside the ```src/etc/``` directory. +* Create a ```querydsl-jpa.activator``` file in the ```src/etc/``` directory. * Open a terminal and type: ```mvn clean compile``` @@ -18,9 +18,9 @@ Of course, you need to define some entities and have **JPA** in your classpath. ## profile activation -Just write a ```src/etc/querydsl-jpa.activator``` file. File contents doesn't matter just file presence. +Just create a ```src/etc/querydsl-jpa.activator``` file. The file contents doesn't matter, it just needs to be present. -The file ```src/etc/querydsl-jpa.activator``` trigger a maven profile that does [all this](http://www.querydsl.com/static/querydsl/4.0.9/reference/html_single/#jpa_integration) for you. +The file ```src/etc/querydsl-jpa.activator``` will trigger a maven profile that does [all this](http://www.querydsl.com/static/querydsl/4.0.9/reference/html_single/#jpa_integration) for you. ## example @@ -82,4 +82,4 @@ import javax.persistence.EntityManager; } ``` -[Querydsl](http://www.querydsl.com/) will find all your entities (classes annotated with @Entity) and generates a class with the same prefixed with ```Q```, like ```QPet```. +[Querydsl](http://www.querydsl.com/) will find all your entities (classes annotated with @Entity) and generates a class with the same name, but prefixed with ```Q```, like ```QPet```. diff --git a/md/doc/security/security.md b/md/doc/security/security.md index 109e29ab99..a35a7d1265 100644 --- a/md/doc/security/security.md +++ b/md/doc/security/security.md @@ -1,6 +1,6 @@ # security -Find here available modules for securing your application but also authenticate and authorize users. +These are the available modules for securing your application and to authenticate and authorize users. ## pac4j diff --git a/md/doc/session/session.md b/md/doc/session/session.md index 4fbf6cee10..0f5f6a7537 100644 --- a/md/doc/session/session.md +++ b/md/doc/session/session.md @@ -1,6 +1,6 @@ # session -Find here the available modules for reading and saving session data in your application. +These are the available modules for reading and saving session data in your application. {{doc/ehcache/ehcache-session.md}} @@ -16,4 +16,4 @@ Find here the available modules for reading and saving session data in your appl {{doc/mongodb/mongodb-session.md}} -{{doc/spymemcached/spymemcached-session.md}} \ No newline at end of file +{{doc/spymemcached/spymemcached-session.md}} diff --git a/md/docker.md b/md/docker.md index 4be68f953b..ecf716552d 100644 --- a/md/docker.md +++ b/md/docker.md @@ -20,7 +20,7 @@ Gradle users might want to choose one of the available [plugins](https://plugins mvn clean package docker:build ``` -* Once it finish, the docker image will be build and tagged as `${project.artifactId}`. +* Once finished, the docker image has been built and tagged as `${project.artifactId}`. * You can now run the image with: @@ -28,7 +28,7 @@ mvn clean package docker:build docker run -p 80:8080 ${project.artifactId} ``` -The Maven profile trigger the [spotify/docker-maven-plugin](https://github.com/spotify/docker-maven-plugin) which generates a `docker` file. Please checkout the [doc](https://github.com/spotify/docker-maven-plugin) for more datails. +The Maven profile triggers the [spotify/docker-maven-plugin](https://github.com/spotify/docker-maven-plugin) which generates a `docker` file. Please see the [doc](https://github.com/spotify/docker-maven-plugin) for more details. ### stork @@ -40,7 +40,7 @@ The Maven profile trigger the [spotify/docker-maven-plugin](https://github.com/s mvn clean package docker:build ``` -* Once it finish, the docker image will be build and tagged as `${project.artifactId}`. +* Once finished, the docker image has been built and tagged as `${project.artifactId}`. * You can now run the image with: @@ -48,4 +48,4 @@ mvn clean package docker:build docker run -it -p 80:8080 ${project.artifactId} ``` -The Maven profile trigger the [spotify/docker-maven-plugin](https://github.com/spotify/docker-maven-plugin) which generates a `docker` file. Please checkout the [doc](https://github.com/spotify/docker-maven-plugin) for more datails. +The Maven profile triggers the [spotify/docker-maven-plugin](https://github.com/spotify/docker-maven-plugin) which generates a `docker` file. Please see the [doc](https://github.com/spotify/docker-maven-plugin) for more details. diff --git a/md/dynamic-routing.md b/md/dynamic-routing.md index c960cdd0c0..aab8da01ed 100644 --- a/md/dynamic-routing.md +++ b/md/dynamic-routing.md @@ -1,8 +1,8 @@ ## dynamic / advanced routing -Dynamic routing allows you to filter a pipeline execution chain and produces custom or completely different response. +Dynamic routing allows you to filter a pipeline execution chain and produces a custom or even completely different response. -For example, suppose you need to serve different content based on hostname: +For example, suppose you need to serve different content based on the hostname: ```java { diff --git a/md/err.md b/md/err.md index be67e92ada..cfbbc765ec 100644 --- a/md/err.md +++ b/md/err.md @@ -1,10 +1,10 @@ # error handling -Error handler is represented by the [Err.Handler]({{defdocs}}/Err.Handler.html) class and allows you to log and/or render exceptions. +An error handler in Jooby is represented by the [Err.Handler]({{defdocs}}/Err.Handler.html) class and allows you to log and render exceptions. ## default err handler -The [default error handler]({{defdocs}}/Err.DefHandler.html) does content negotiation and optionally display friendly err pages using naming convention. +The [default error handler]({{defdocs}}/Err.DefHandler.html) does content negotiation and optionally displays friendly error pages using a naming convention. ```java { @@ -21,7 +21,7 @@ The [default error handler]({{defdocs}}/Err.DefHandler.html) does content negoti ### html -If a request to ```/``` has an ```Accept: text/html``` header. Then, the default err handler will +If a request to ```/``` has an ```Accept: text/html``` header. Then, the default Err handler will ask to a [View.Engine]({{defdocs}}/View.Engine.html) to render the ```err``` view. The default model has these attributes: @@ -31,7 +31,7 @@ The default model has these attributes: * status: status code, like ```400``` * reason: status code reason, like ```BAD REQUEST``` -Here is a simply ```public/err.html``` error page: +Here is a simple ```public/err.html``` error page: ```html @@ -41,12 +41,12 @@ Here is a simply ```public/err.html``` error page: ``` -HTTP status code will be set too. +The HTTP status code of the response will be set as well. ### no html -If a request to ```/``` has an ```Accept: application/json``` header. Then, the default err handler will -ask to a [renderer]({{defdocs}}/Renderer.html) to render the ```err``` model. +If a request to ```/``` has an ```Accept: application/json``` header, the default Err handler will +use a [renderer]({{defdocs}}/Renderer.html) to render the ```err``` model. ```json { @@ -59,11 +59,11 @@ ask to a [renderer]({{defdocs}}/Renderer.html) to render the ```err``` model. In both cases, the error model is the result of ```err.toMap()``` which creates a lightweight version of the exception. -HTTP status code will be set too. +The HTTP status code of the response will be set as well. ## custom err handler -If the default view resolution and/or err model isn't enough, you can create your own err handler: +If the default view resolution and/or err model isn't enough, you can create your own Err handler: ```java { @@ -75,10 +75,10 @@ If the default view resolution and/or err model isn't enough, you can create you } ``` -Err handler are executed in the order they were provided (like routes, parsers and renderers). -The first err handler that send an output wins! +The Err handlers are executed in the order they were provided (like routes, parsers and renderers). +The first Err handler that send an output wins! -### catch specific exception or status code +### catch a specific exception or status code ```java @@ -119,7 +119,7 @@ Or you can catch exception base on their response status code (see next section) ## status code -Default status code is ```500```, except for: +The default status code for errors is ```500```, except for: ``` | Exception | Status Code | @@ -131,7 +131,7 @@ Default status code is ```500```, except for: | java.io.FileNotFoundException | 404 | ``` -### custom status code +### custom status codes Just throw an [Err]({{defdocs}}/Err.html): @@ -145,4 +145,4 @@ or add a new entry in the ```application.conf``` file: err.com.security.Forbidden = 403 ``` -So, now if you throw a ```com.security.Forbidden``` exception the status code will be ```403```. +When you now throw a ```com.security.Forbidden``` exception, the status code will be ```403```. diff --git a/md/faq.md b/md/faq.md index d073909887..16d1dafe0d 100644 --- a/md/faq.md +++ b/md/faq.md @@ -26,17 +26,17 @@ ## can I use Gradle? -Yes, with some limitation that are being documented [here](/doc/gradle). +Yes, with some limitations that are being documented [here](/doc/gradle). ## how do I run code on start/stop? -Documentation for [lyfeCycle]({{defdocs}}/LyfeCycle.html) events is available [here](/doc/#application-life-cycle) +Documentation for [lifeCycle]({{defdocs}}/LifeCycle.html) events is available [here](/doc/#application-life-cycle) # mime types ## what mime types are supported? -* Full list of mime types can be found [here](/doc/#misc-mime-properties) +* Full list of MIME types can be found [here](/doc/#misc-mime-properties) ## how do I add a new/override mime type? diff --git a/md/fatjar.md b/md/fatjar.md index d7eb938dc0..ec239933cc 100644 --- a/md/fatjar.md +++ b/md/fatjar.md @@ -2,7 +2,7 @@ This is the default deployment option and you (usually) don't need to do anything if you created your application via [maven archetype](/quickstart). -In order to create a **fat jar** go to your project home, open a terminal and run: +In order to create a **fat jar**, go to your project home, open a terminal and run: ``` mvn clean package @@ -50,12 +50,12 @@ If you created your application via [maven archetype](/quickstart) this setup is ## run / start -Due everything was bundle into a single ```jar``` file, all you have to do is: +Since everything was bundled into a single ```jar```, all you have to do is: ```bash java -jar myapp.jar [env] ``` -Easy hugh? No complex deployment, **no heavy-weight servers**, **no classpath hell**, nothing!!! +Easy huh? No complex deployment, **no heavy-weight servers**, **no classpath hell**, nothing! -Your application is up and running!! +Your application is up and running! diff --git a/md/gradle-jooby-run.md b/md/gradle-jooby-run.md index 7327773d95..87da71f50b 100644 --- a/md/gradle-jooby-run.md +++ b/md/gradle-jooby-run.md @@ -26,7 +26,7 @@ apply plugin: 'jooby' gradle joobyRun ``` -Prints something similar to: +It will print something like this: ```bash >>> jooby:run[info|main]: Hotswap available on: /my-app @@ -43,14 +43,14 @@ listening on: ## hot reload -The ```joobyRun``` tool restart the application every time a change is detected on: +The ```joobyRun``` tool restarts the application each time a change is detected on: - classes (*.class) - config files (*.conf and *.properties) -Changes on templates and/or static files (*.html, *.js, *.css) wont restart the application, because they are not compiled or cached while running on ```application.env = dev```. +Changes on templates and/or static files (*.html, *.js, *.css) won't restart the application, because they are not compiled or cached while running on ```application.env = dev```. -It's worth to mention that dynamic reload of classes is done via {{jboss-modules}}. +It's worth mentioning that dynamic reload of classes is done via {{jboss-modules}}. ## options @@ -74,7 +74,7 @@ A {{gradle}} property that contains the fully qualified name of the ```main clas The compiler is ```on``` by default, unless: -* A ```.classpath``` file is present in the project directory. If present, means you're a Eclipse user and we turn off the compiler and let Eclipse recompiles the code on save. +* A ```.classpath``` file is present in the project directory. If present, it's assumed you're using Eclipse and the compiler is disabled, letting Eclipse recompile the code on save. * The compiler is set to ```off```. @@ -82,8 +82,8 @@ On compilation success, the application is effectively reloaded. On compilation error, the application won't reload. -Compilation success or error messages are displayed in the console (not at the browser). +Compilation success or error messages are displayed in the console (not in the browser). ### includes / excludes -List of file patterns to listen for file changes. +List of file patterns to watch for file changes. diff --git a/md/guides/deployment.md b/md/guides/deployment.md index 50097414ae..8dd1de7887 100644 --- a/md/guides/deployment.md +++ b/md/guides/deployment.md @@ -15,17 +15,17 @@ In order to create a **fat jar** go to your project home, open a terminal and ru mvn clean package ``` -Once it finish, the jar will be available inside the ```target``` directory. +Once it's finished, the jar will be available inside the ```target``` directory. ## run / start -Due everything was bundle into a single ```jar``` file, all you have to do is: +Since everything was bundle into a single ```jar``` file, all you have to do is: ```bash java -jar myapp.jar ``` -Pretty easy! No complex deployment, **no heavy-weight servers**, **no classpath hell**, nothing!!! Your application is up and running!! +Pretty easy! No complex deployment, **no heavy-weight servers**, **no classpath hell**. Your application is up and running! ## env and conf @@ -33,7 +33,7 @@ Pretty easy! No complex deployment, **no heavy-weight servers**, **no classpath The ```application.env``` property controls the ```environment```, by default this property is set to ```dev``` (the unique and well known env). -Now, suppose you need to deploy your awesome app into ```prod``` and you need to set/update a few properties. The ```application.conf``` file looks like: +Now, suppose you need to deploy your awesome app into ```prod``` and you need to set a few properties. The ```application.conf``` file looks like: ``` ... @@ -42,14 +42,14 @@ aws.secretKey = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY ... ``` -Now, for ```prod``` you have a new key pair... then all you have to do is to create a new file ```application.prod.conf``` and just add those new keys: +Now, for ```prod``` you have a new key value pair... all you have to do is to create a new file ```application.prod.conf``` and just add those new keys: ``` aws.accessKey = AKIAIOSFODNN7PROD aws.secretKey = wJalrXUtnFEMI/K7MDENG/bPxRfiCYPROD ``` -> **TIP**: You don't have to add all the properties, just those who are different for the environment. +> **TIP**: You don't have to add all the properties, just those which differ for the environment. The final step is to start the app with ```application.env=prod```: @@ -57,14 +57,13 @@ The final step is to start the app with ```application.env=prod```: java -Dapplication.env=prod myapp.jar ``` -Your application will run now in ```prod```. It will find your ```application.conf``` and overrides in property defined there with those from ```application.prod.conf``` +Your application will run now in ```prod```. It will find your ```application.conf``` and overrides the properties defined there with those from ```application.prod.conf``` -It works for ```logback.xml``` too, if ```logback.[env].xml``` is present, then **Jooby** will use it, otherwise it fallbacks to ```logback.xml```. +It works for ```logback.xml``` too, if ```logback.[env].xml``` is present, then **Jooby** will use it, otherwise it falls back to ```logback.xml```. # zip deployment -A **Jooby** app created from {{maven}} ```archetype``` will also generates a ```myapp.zip``` file, every time you run: - +A **Jooby** app created from {{maven}} ```archetype``` will also generates a ```myapp.zip``` file, each time you run: ``` mvn clean package @@ -86,7 +85,7 @@ This ```.zip``` file **mimics** a typical server layout: The scripts: ```start/stop.sh``` are very simple and they will start/stop a **Jooby** app. -The scripts are inside the ```src/etc/bin``` directory you can edit them, add more, etc... They will be always included in the final ```.zip```. +The scripts are inside the ```src/etc/bin``` directory you can edit them, add more, etc. They will be always included in the final ```.zip```. The ```zip``` deployment makes sense when you want to have more control over your application. For example: @@ -115,7 +114,7 @@ The ```maven-assembly-plugin``` will generate the ```.zip``` file. ## run / start -It is usually don't via ```start.sh```: +Usually done via ```start.sh```: ``` ./start.sh prod @@ -127,8 +126,8 @@ It works like the [jar deployment](#jar-deployment-env-and-conf) # conclusion -**Jar deployment** makes perfect sense for PaaS like Heroku, AppEngine, etc... +**Jar deployment** makes perfect sense for PaaS like Heroku, AppEngine, etc. **Zip deployment** give you more control for starting and stopping but also control the application log at runtime. -Happy coding!! +Happy coding! diff --git a/md/guides/greeting.md b/md/guides/greeting.md index 7f45c205fa..c6c88a99fa 100644 --- a/md/guides/greeting.md +++ b/md/guides/greeting.md @@ -155,7 +155,7 @@ What if you call the service without a ```name```? You will get a ```Bad Request Same as before, we ask for the HTTP parameter but this time we set a default value: ```World```. -The {{javadoc "Mutant" "value" "java.lang.String"}} is syntax sugar for: +The {{javadoc "Mutant" "value" "java.lang.String"}} is syntactical sugar for: ``` String name = req.param("name").toOptional().orElse("World"); @@ -203,13 +203,13 @@ Nice huh? # json -{{jooby}} is a micro-web framework, so in order to write a **JSON** response we need one of the available {{link "/doc/parser-and-renderer" "json modules"}}. +{{jooby}} is a micro-web framework, so in order to write a **JSON** response you will need one of the available {{link "/doc/parser-and-renderer" "json modules"}}. -Here we will use {{modlink "jackson"}} but keep in mind the process is exactly the same if you choose any other module. +In this example we'll use {{modlink "jackson"}} but the process is exactly the same if you choose any of the other modules. ## dependency -Let's add the {{modlink "jackson"}} dependency to your project: +Let's add the {{modlink "jackson"}} dependency to the project: ```xml @@ -243,9 +243,9 @@ import org.jooby.json.Jackson; } ``` -Our service method didn't change at all! we just {{javadoc "Jooby" "use" "org.jooby.Jooby.Module" label="use"}} the {{modlink "jackson"}} module!! +Our service method didn't change at all! we just {{javadoc "Jooby" "use" "org.jooby.Jooby.Module" label="use"}} the {{modlink "jackson"}} module! -Try it +Try accessing http://localhost:8080/greeting @@ -297,9 +297,9 @@ Go to `App.java` and add this line: } ``` -We try to keep `reflection`, `classpath scanning` and `annotations` to minimum that is one of reason why they need to be explicitly registered. +Jooby tries to keep `reflection`, `classpath scanning` and `annotations` to a minimum. That is one of the reasons why routes need to be explicitly registered. -The other reason is the **route order**, because routes are executed in the **order** they are defined. +The other reason is the **route order**, since routes are executed in the **order** they are defined. Having said that, we do offer a service {{modlink "scanner"}} module that automatically registers `MVC` routes. @@ -309,7 +309,7 @@ Try it: ## adding a name parameter -As we did with the script route, we are going to add a **required** `name` parameter: +As with the script route, we are going to add a **required** `name` parameter: ```java @Path("/greeting") @@ -376,7 +376,7 @@ This is an unrealistic **JSON API**, but it helps to demonstrate how simple and We also demonstrate the **script** and **mvc** programming models, you can pick one or mix both in a single application. -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. +The **script** programming model is perfect for getting things done quickly and/or for small applications. It is also possible to use the **script** routes on larger applications, where you usually split routes in one or more applications and then you compose all those small application into one. The **mvc** programming model is a bit more verbose but probably better for large scale applications. diff --git a/md/h2.md b/md/h2.md index 5bb1a8f611..f1771a7967 100644 --- a/md/h2.md +++ b/md/h2.md @@ -1,6 +1,6 @@ # http/2 -`HTTP/2.0` is supported across the available [server implementations](/doc/servers). To enabled `HTTP/2.0` you need to set these properties: +`HTTP/2.0` is supported across the available [server implementations](/doc/servers). To enable `HTTP/2.0` you need to set these properties: ``` server.http2.enabled = true @@ -22,7 +22,7 @@ Or programmatically like: } ``` -Browsers don't support `H2C` (H2 clear text) so that's why you need to configure [HTTPS](/doc/#https) too. +Browsers don't support `H2C` (H2 clear text) which is why you need to configure [HTTPS](/doc/#https) as well. At `bootstrap time` you will see a `+h2` flag that indicates that `HTTP/2.0` is enabled: @@ -31,7 +31,7 @@ At `bootstrap time` you will see a `+h2` flag that indicates that `HTTP/2.0` is https://localhost:8443/ +h2 ``` -Some servers require special configuration (beside [HTTPS](/doc/#https)). So it's always a good practice to check the `HTTP/2.0` section of the server implementation to learn more about current support, limitation and/or configuration steps. +Some servers require special configuration (besides [HTTPS](/doc/#https)). So it's always good practice to check the `HTTP/2.0` section of the server implementation to learn more about current support, limitations and/or configuration steps. ## server push @@ -56,6 +56,6 @@ Server push is supported via [Request.push]({{defdocs}}/Request.html#push-java.l } ``` -When the *browser* request the `home` page, we will send the `/js/home.js` resource too!! +When the *browser* requests the `home` page, we will send the `/js/home.js` resource as well! -That's all, but keep in mind each server implementation might require some extra configuration steps to work, please check out the [server documentation](/doc/servers) for more details. +That's all, but keep in mind that each server implementation might require some extra configuration steps to work, please check out the [server documentation](/doc/servers) for more details. diff --git a/md/https.md b/md/https.md index 81b328c1a6..53830fdc38 100644 --- a/md/https.md +++ b/md/https.md @@ -30,7 +30,7 @@ Optionally, you can set these properties too: * ```ssl.session.cacheSize```: Set the size of the cache used for storing SSL session objects. 0 to use the default value. * ```ssl.session.timeout```: Timeout for the cached SSL session objects, in seconds. 0 to use the default value. -As you can see setup is very simple. All you need is your ```.crt``` and ```.key``` files. +As you can see, setup is very simple. All you need is your ```.crt``` and ```.key``` files. At startup you will see a line similar to this one: diff --git a/md/interceptors.md b/md/interceptors.md index c0bbf40391..e5a42fa1df 100644 --- a/md/interceptors.md +++ b/md/interceptors.md @@ -1,10 +1,10 @@ ## interceptors -An interceptor allows to customize a HTTP request and response at three stages: +An interceptor allows to customize an HTTP request and response at three stages: * **before** the actual handler is invoked * **after** the handler was executed, but before we send the response -* when response is **complete** and sendt +* when the response is **complete** and sent ### before @@ -19,7 +19,7 @@ Allows for customized handler execution chains. It will be invoked before the ac } ``` -You are allowed to modify the [request]({{defdocs}}/Request.html) and [response]({{defdocs}}/Response.html) objects. Please note that the ```before``` handler is just syntax sugar for {{req_filter}}. For example, the ```before``` handler was implemented as: +You are allowed to modify the [request]({{defdocs}}/Request.html) and [response]({{defdocs}}/Response.html) objects. Please note that the ```before``` handler is just syntactic sugar for {{req_filter}}. For example, the ```before``` handler was implemented as: ```java { @@ -30,7 +30,7 @@ You are allowed to modify the [request]({{defdocs}}/Request.html) and [response] } ``` -A ```before``` handler must to be registered before (of course) the actual handler you want to intercept. +A ```before``` handler must be registered before the actual handler you want to intercept. ```java { @@ -48,11 +48,11 @@ A ```before``` handler must to be registered before (of course) the actual handl If you reverse the order, it won't work. -> **Remember**: routes are executed in the order they are defined and the pipeline is executed as long you don't generate a response. +> **Remember**: routes are executed in the order they are defined and the pipeline is executed as long as you don't generate a response. ### after -Allows for customize response before sending it. It will be invoked at the time a response need to be send. +Allows for customization of the response before sending it. It will be invoked at the time a response need to be sent. ```java { @@ -64,7 +64,7 @@ Allows for customize response before sending it. It will be invoked at the time } ``` -You are allowed to modify the [request]({{defdocs}}/Request.html), [response]({{defdocs}}/Response.html) and [result]({{apidocs}}/org/jooby/Result.html) object. The handler returns a {{result}} which can be the same or an entirely new {{result}}. Please note that the ```after``` handler is just syntax sugar for {{req_filter}}. For example, the ```after``` handler was implemented as: +You are allowed to modify the [request]({{defdocs}}/Request.html), [response]({{defdocs}}/Response.html) and [result]({{apidocs}}/org/jooby/Result.html) object. The handler returns a {{result}} which can be the same or an entirely new {{result}}. Please note that the ```after``` handler is just syntactical sugar for {{req_filter}}. For example, the ```after``` handler was implemented as: ```java { @@ -79,7 +79,7 @@ You are allowed to modify the [request]({{defdocs}}/Request.html), [response]({{ } ``` -Due ```after``` is implemented by wrapping the [response]({{defdocs}}/Response.html) object. A ```after``` handler must to be registered before the actual handler you want to intercept. +Since ```after``` is implemented by wrapping the [response]({{defdocs}}/Response.html) object. An ```after``` handler must be registered before the actual handler you want to intercept. ```java { @@ -95,13 +95,13 @@ Due ```after``` is implemented by wrapping the [response]({{defdocs}}/Response.h } ``` -If you reverse the order then it won't work. +If you reverse the order, it won't work. > **Remember**: routes are executed in the order they are defined and the pipeline is executed as long you don't generate a response. ### complete -Allows for log and cleanup a request. It will be invoked after we send a response. +Allows for logging and cleaning up of a request. Invoked after the response is sent. ```java { @@ -112,7 +112,7 @@ Allows for log and cleanup a request. It will be invoked after we send a respons } ``` -You are **NOT** allowed to modify the {{request}} and {{response}} objects. The ```cause``` is an ```Optional``` with a ```Throwable``` useful to identify problems. The goal of the ```complete``` handler is to probably cleanup request object and log responses. Please note that the ```complete``` handler is just syntax sugar for {{req_filter}}. For example, the ```complete``` handler was implemented as: +You are **NOT** allowed to modify the {{request}} and {{response}} objects. The ```cause``` is an ```Optional``` with a ```Throwable``` useful to identify problems. A common use case for the ```complete``` handler is to clean up the request object and to log responses. Please note that the ```complete``` handler is just syntactical sugar for {{req_filter}}. For example, the ```complete``` handler was implemented as: ```java { @@ -144,7 +144,7 @@ A ```complete``` handler must to be registered before the actual handler you wan } ``` -If you reverse the order then it won't work. +If you reverse the order, it won't work. > **Remember**: routes are executed in the order they are defined and the pipeline is executed as long you don't generate a response. diff --git a/md/javascript.md b/md/javascript.md index 7eb2784b44..688d9f30a9 100644 --- a/md/javascript.md +++ b/md/javascript.md @@ -14,7 +14,7 @@ ## usage -Write an `app.js` file inside your project directory: +Create an `app.js` file in your project directory: ```js @@ -24,7 +24,7 @@ app.get('/', function () 'Hey Jooby!'); ``` -Go to your `pom.xml` and update/set the `application.class` property to `org.jooby.JoobyJs` like: +In your `pom.xml`, set the `application.class` property to `org.jooby.JoobyJs` like this: ```xml @@ -32,7 +32,7 @@ Go to your `pom.xml` and update/set the `application.class` property to `org.joo ``` -The `org.jooby.JoobyJs` class setup [Nashorn](http://openjdk.java.net/projects/nashorn/) and startup `Jooby`. +The `org.jooby.JoobyJs` class will set up [Nashorn](http://openjdk.java.net/projects/nashorn/) and start `Jooby`. ## jooby function @@ -52,7 +52,7 @@ jooby(function () { })(); ``` -Another minor but useful feature is the: **import of classes** and **packages** when you go with the functional version: +Another minor, but useful feature is the: **import of classes** and **packages** when you go with the functional version: ```js jooby(function (Jackson) { @@ -76,11 +76,11 @@ jooby(function (Jackson) { })(org.jooby.json); ``` -Import of packages is done via: ```importPackage``` function from in ```nashorn:mozilla_compat.js```. +Import of packages is done via: ```importPackage``` function from ```nashorn:mozilla_compat.js```. ## routes -Routes work as in Java, but it is worth to mention what are the available alternatives at the time you need to write a route in JavaScript: +Routes work as in Java, but it is worth mentioning the available alternatives when you write a route in JavaScript: ```js jooby(function () { @@ -93,18 +93,18 @@ jooby(function () { return 'Hey Jooby!'; }); - // returns a value but access to request object + // returns a value, but with access to the request object this.get('/', function (req) { var x = require(X) return x.doSomething(); }); - // access to request and rsp (like in express.js) + // access to the request and the response (as in express.js) this.get('/', function (req, rsp) { rsp.send('Hey Jooby!'); }); - // access to request and rsp + // access to the request and the response this.get('/', function (req, rsp, chain) { chain.next(); }); diff --git a/md/jooby-pre.md b/md/jooby-pre.md index 0d589cd168..905f5d1dee 100644 --- a/md/jooby-pre.md +++ b/md/jooby-pre.md @@ -10,4 +10,4 @@ * **Simple, effective and easy to learn**. Ideal for small but also large scale applications. -* **Ready for modern web**, with the awesome and powerful [asset module](https://github.com/jooby-project/jooby/tree/master/jooby-assets) +* **Ready for the modern web**, with the awesome and powerful [asset module](https://github.com/jooby-project/jooby/tree/master/jooby-assets) diff --git a/md/kotlin.md b/md/kotlin.md index 830c300e0f..e6f96b375e 100644 --- a/md/kotlin.md +++ b/md/kotlin.md @@ -1,6 +1,6 @@ # kotlin -We do provide a very tiny module with some special functions that makes a {{jooby}} application more Kotlin idiomatic. +{{jooby}} provides a tiny module with some functions that will make an application more Kotlin idiomatic. ## dependency @@ -35,7 +35,7 @@ The `run` function is a [type-safe builder](http://kotlinlang.org/docs/reference ### request access -Access to {{request}} is available via **request callback**: +Access to the {{request}} is available via a **request callback**: ```java run(*args) { @@ -46,7 +46,7 @@ run(*args) { } ``` -The **request** idiom gives you implicit access to the {{request}} object, previous example can be written as: +The **request** idiom gives you implicit access to the {{request}} object. The previous example can be written as: ```java run(*args) { @@ -60,7 +60,7 @@ run(*args) { ### route group -This idiom allow to group one or more routes under a common `path`: +This idiom allows grouping one or more routes under a common `path`: ```java run(*args) { @@ -84,7 +84,7 @@ run(*args) { ### class reference -We do provide `Kotlin class references` where a `Java class reference` is required. +{{jooby}} provides a `Kotlin class references` where a `Java class reference` is required. Example 1: Register a `MVC routes` @@ -111,7 +111,7 @@ run(*args) { ### JSON API -Next example uses the [jackson module](/doc/jackson) to parse and render `JSON`: +The next example uses the [jackson module](/doc/jackson) to parse and render `JSON`: ```java @@ -161,6 +161,6 @@ fun main(args: Array) { ## starter project -We do provide a [kotlin-starter](https://github.com/jooby-project/kotlin-starter) project. Go and [fork it](https://github.com/jooby-project/kotlin-starter). +{{jooby}} provides a [kotlin-starter](https://github.com/jooby-project/kotlin-starter) project. Go and [fork it](https://github.com/jooby-project/kotlin-starter). -That's all folks!! +That's all folks! diff --git a/md/logging.md b/md/logging.md index 9bce41cae9..62c7c21a56 100644 --- a/md/logging.md +++ b/md/logging.md @@ -7,4 +7,4 @@ You will usually find the `logback.xml` file inside the `conf` directory. Also, * `logback.uat.xml` when `application.env = uat` * `logback.prod.xml` when `application.env = prod` -Of course if the `logback[.env].xml` isn't, present we fallback to default one `logback.xml`. +If the `logback[.env].xml` file isn't present, `logback.xml` will be used as a fallback. diff --git a/md/modules.md b/md/modules.md index 5b16f03da4..bdaf9a3f08 100644 --- a/md/modules.md +++ b/md/modules.md @@ -6,25 +6,25 @@ Modules (unlike in other frameworks) are thin and do a lot of work to bootstrap Modules like in [Guice](https://github.com/google/guice) are used to wire services, connect data, etc... -There is an extensive [module ecosystem](/modules) which makes Jooby a **full stack** framework (when need it). +There is an extensive [module ecosystem](/modules) which makes Jooby a **full stack** framework (when needed). ## do less and be flexible **Do less** might sounds confusing, but is the key to **flexibility**. -A module does as **less as possible** (key difference with other frameworks). A module for a library `X` should: +A module does as **little as possible** (a key difference with other frameworks). A module for a library `X` should: * Bootstrap X * Configure X -* exports API of X +* export the API of X -This means a module should NOT create wrapper for a library. Instead, provides a way to extend, configure and use the external library. +This means that a module should NOT create a wrapper for a library. Instead it should provide a way to extend, configure and use the external library. -> This principle, keep module usually small, maintainable and flexible. +> This principle keeps modules small, maintainable and flexible. ## creating modules -A module is represented by the [Jooby.Module]({{defdocs}}/Jooby.Module.html) class. The configure callback looks like: +A module is represented by the [Jooby.Module]({{defdocs}}/Jooby.Module.html) class. The configure callback looks like this: ```java public class M1 implements Jooby.Module { @@ -56,7 +56,7 @@ public class M1 implements Jooby.Module { ## usage -A module must be imported/registered at startup time: +A module must be registered at startup time: ```java @@ -77,7 +77,7 @@ public class MyApp extends Jooby { } ``` -You can start/stop services from a module: +You can start or stop services from a module: ```java public class M1 implements Jooby.Module { @@ -98,7 +98,7 @@ Or export routes: public class M1 implements Jooby.Module { public void configure(Env env, Config config, Binder binder) { Router router = env.router(); - router.get("/m1", () -> "I'm a module!!!"); + router.get("/m1", () -> "I'm a module!"); } } ``` diff --git a/md/mvc-routes.md b/md/mvc-routes.md index 2907f745db..a22b1473b2 100644 --- a/md/mvc-routes.md +++ b/md/mvc-routes.md @@ -1,6 +1,6 @@ ## mvc routes -Mvc routes are like **controllers** in [Spring](http://spring.io) and/or **resources** in [Jersey](https://jersey.java.net/) with some minor enhancements and/or simplifications. +Mvc routes are similar to **controllers** in [Spring](http://spring.io) and **resources** in [Jersey](https://jersey.java.net/) with some minor enhancements and simplifications. ```java @Path("/") @@ -15,7 +15,7 @@ public class MyRoutes { Annotations are identical to [Jersey/JAX-RS](https://jersey.java.net/) and they can be found under the package `org.jooby.mvc`. -> **NOTE**: Jooby doesn't implement the **JAX-RS** specification that is why it has its own version of the annotations. +> **NOTE**: Jooby doesn't implement the **JAX-RS** specification. That is why it has its own version of the annotations. An mvc route can be injected by {{guice}}: @@ -49,7 +49,7 @@ public class MyRoutes { } ``` -> **NOTE**: MVC routes **are NOT singleton**, unless you explicitly annotated the route as Singleton: +> **NOTE**: MVC routes **are NOT singleton**, unless you explicitly annotated the route as a Singleton: ```java @@ -177,7 +177,7 @@ Same for {{file_upload}} } ``` -Jooby uses the method parameter name and binds that name to a request parameter. If you want an explicit mapping and/or the request parameter isn't a valid Java identifier: +Jooby uses the method parameter name and binds that name to a request parameter. If you want an explicit mapping or if the request parameter isn't a valid Java identifier: ```java @GET @@ -220,7 +220,7 @@ Annotate the method parameter with the [@Header]({{defdocs}}/mvc/Header.html) an } ``` -Or, if the header name isn't a valid Java identifier +Or, if the header name isn't a valid Java identifier: ```java @GET @@ -231,7 +231,7 @@ Or, if the header name isn't a valid Java identifier ### response -A method returns type is sent to the client. Some examples: +A methods return type is sent to the client. Some examples: ```java @@ -249,7 +249,7 @@ public Result dontSayGoodbye(String name) { ``` -If you need/want to render a view, just return a [view]({{defdocs}}/View.html) instance: +If you want to render a view, just return a [view]({{defdocs}}/View.html) instance: ```java @GET @@ -258,7 +258,7 @@ public Result home() { } ``` -If you need to deal with HTTP metadata like: status code, headers, etc... use a [result] as method return type: +If you need to deal with HTTP metadata like: status code, headers, etc... use a [result] as the return type: ```java @GET diff --git a/md/quickstart.md b/md/quickstart.md index edb5fc8706..736f10aec2 100644 --- a/md/quickstart.md +++ b/md/quickstart.md @@ -44,7 +44,7 @@ listening on: http://0.0.0.0:8080/ ``` -**Jooby**! is up and running!!! +**Jooby**! is up and running! getting started ===== @@ -52,7 +52,7 @@ getting started exploring the newly created project ----- -A new directory was created: ```my-app```. Now, let's see how it looks like: +A new directory was created: ```my-app```. Let's see how it looks like: ```bash . @@ -74,11 +74,11 @@ A new directory was created: ```my-app```. Now, let's see how it looks like: └── AppTest.java ``` -The **public** folder contains static files like ```*.html```, ```*.js```, ```*.css```, ..., ```*.png``` files. +The **public** folder contains static content like ```*.html```, ```*.js```, ```*.css```, ..., ```*.png``` files. The **conf** folder contains ```*.conf```. -The **src/main/java** folder contains ```*.java``` (of course) files. +The **src/main/java** folder contains ```*.java``` files (of course). The **src/test/java** folder contains unit and integration tests. @@ -108,7 +108,7 @@ public class App extends Jooby { // 1 Steps involved are: -1) extends Jooby +1) extend Jooby 2) define some routes @@ -117,17 +117,17 @@ Steps involved are: running ----- -Just open a console and type: +Open a console and type: mvn jooby:run -The maven plugin will compile the code (if necessary) and startup the application. +The maven plugin will compile the code (if necessary) and start the application. -Of course, you can generate the IDE metadata from Maven and/or import as a Maven project in your favorite IDE. -Then all you have to do is run the: ```App.java``` class. After all, this is plain Java application with a ```main``` method. +Of course, you can generate the IDE metadata from Maven or import as a Maven project in your favorite IDE. +Afterwards, all you have to do is run the: ```App.java``` class. After all, this is a plain Java application with a ```main``` method. where to go now? ----- * read the [documentation](/doc) -* checkout one of our {{templates}} +* check out one of the {{templates}} diff --git a/md/req.md b/md/req.md index 228aa77283..f51549a6f3 100644 --- a/md/req.md +++ b/md/req.md @@ -1,12 +1,12 @@ # request -The request object contains methods for reading parameters, headers and body (among others). In the next section we will mention the most important method of a {{request}} object, if you need more information please refer to the [javadoc]({{apidocs}}/org/jooby/Request.html). +The request object contains methods for reading parameters, headers and body (amongst others). In the next section, the most important methods of a {{request}} object will be explored. If you need more information, please refer to the [javadoc]({{apidocs}}/org/jooby/Request.html). ## parameters -Retrieval of parameter is done via: {{req_param}} method. +Retrieval of a parameter is done via the: {{req_param}} method. -The {{req_param}} **always** returns a {{mutant}} instance. A {{mutant}} had severals utility methods for doing type conversion: +The {{req_param}} method **always** returns a {{mutant}} instance. A {{mutant}} has several utility methods for doing type conversion: ```java get("/", req -> { @@ -69,21 +69,21 @@ public class Address { } ``` -Bean class must have a ```default constructor``` or a constructor annotated with `javax.inject.Inject`. +Bean classes must have a ```default constructor``` or a constructor annotated with `javax.inject.Inject`. ### parameter type and precedence -A {{request}} parameter can be present at: +A {{request}} parameter can be present in: -1) **path level**: `/user/:id` +1) **path**: `/user/:id` -2) **query query**: `/user?id=...` +2) **query string**: `/user?id=...` 3) **form submit** encoded as {{formurlencoded}} or {{formmultipart}} -(first listed are higher precedence) +(parameters take precedence in the order listed) -Now, let's suppose a very poor API where we have a route handler that accept an **id** parameter in the 3 location: +For example purposes, let's consider a poorly constructed API where we have a route handler that accepts an **id** parameter in all three locations: A call like: @@ -107,7 +107,7 @@ get("/user/:id", req -> { }); ``` -It is clear that an API like this should be avoided, but is a good example of parameter precedence. +While clearly bad API design, this is a good example of how parameter precedence works. ### parameter type conversion @@ -120,7 +120,7 @@ Automatic type conversion is provided when a type: * Has a static method **valueOf** that accepts a single **String** argument * Has a static method **fromString** that accepts a single **String** argument. Like ```java.util.UUID``` * Has a static method **forName** that accepts a single **String** argument. Like ```java.nio.charset.Charset``` -* It is an Optional, List, Set or SortedSet where T satisfies one of previous rules +* Is an Optional, List, Set or SortedSet where T satisfies one of the previous rules Custom type conversion is also possible: @@ -144,17 +144,17 @@ See [parser and renderer](/doc/#parser-and-renderer). ## headers -Retrieval of request headers is done via: {{req_header}}. All the explained before for [request params](#request-parameters) apply for headers too. +Retrieval of request headers is done via: {{req_header}}. What goes for the [request params](#request-parameters) applies for the headers as well. ## body -Retrieval of request body is done via {{req_body}} or {{req_bodyc}}. +Retrieval of the request body is done via {{req_body}} or {{req_bodyc}}. -A {{parser}} is responsible for parse or convert the HTTP request body to something else. +A {{parser}} is responsible for either parsing or converting the HTTP request body to something else. -There are a few built-in parsers for reading body as `String`, `primitives`, ..., etc. +There are a few built-in parsers for reading the body as `String`, `primitives`, ..., etc. -[Parsers](/doc/#parser-and-renderer) are explained later. For now, all you need to know is that they can read/parse the HTTP body. +[Parsers](/doc/#parser-and-renderer) are explained later. For now, all you need to know is that they can read or parse the HTTP body. Script API: @@ -182,11 +182,11 @@ public class Controller { } ``` -> **NOTE**: Don't use {{req_body}}, {{req_bodyc}} or [@Body]({{defdocs}}/mvc/Body.html) for `POST` encoded as {{formurlencoded}} or {{formmultipart}}, see next section for such requests. +> **NOTE**: Don't use {{req_body}}, {{req_bodyc}} or [@Body]({{defdocs}}/mvc/Body.html) for a `POST` request encoded as {{formurlencoded}} or {{formmultipart}}, see the next section for such requests. ## form submit -Form submit parsing is done via [req.params(Class)]({{defdocs}}/Request.html#params-java.lang.Class-) or [req.form(Class)]({{defdocs}}/Request.html#form-java.lang.Class-) method: +Form submit parsing is done via [req.params(Class)]({{defdocs}}/Request.html#params-java.lang.Class-) or the [req.form(Class)]({{defdocs}}/Request.html#form-java.lang.Class-) method: ```java public class Contact { @@ -284,7 +284,7 @@ public class Address { ``` -Tabular data is supported too: +Tabular data is supported as well: ```java public class Contact { @@ -320,9 +320,9 @@ public class Contact { ``` -> **NOTE**: Constructor injection of nested or tabular objects isn't supported. Nested/tabular object are injected via method or field. +> **NOTE**: Constructor injection of nested or tabular objects isn't supported. Nested/tabular object are injected via either method or field. -The injection rules are defined as follow (first listed are higher priority): +The injection rules are defined as follows (higher priority first): * There is a only one constructor (nested/tabular data can't be injected, just simple values). * There are more than a single constructor but only one annotated with `javax.inject.Inject` (nested/tabular data can't be injected, just simple values). @@ -331,7 +331,7 @@ The injection rules are defined as follow (first listed are higher priority): ## file upload -File uploads are accessible via: [request.file(name)]({{defdocs}}/Request.html#file-java.lang.String-) method: +File uploads are accessible via the: [request.file(name)]({{defdocs}}/Request.html#file-java.lang.String-) method: ```html
@@ -365,7 +365,7 @@ You must close a {{file_upload}} in order to release resources: ## locals -Local attributes (a.k.a request attributes) are bound to the current request. They are created every time a new request comes in and destroyed at the end of the request. +Local attributes (a.k.a request attributes) are bound to the current request. They are created every time a new request is received and destroyed at the end of the request cycle. ```java { @@ -390,7 +390,7 @@ Local attributes (a.k.a request attributes) are bound to the current request. Th } ``` -In ```mvc routes``` request locals can be injected via ```@Local``` annotation: +In ```mvc routes``` request locals can be injected via the ```@Local``` annotation: ```java @@ -413,9 +413,9 @@ In ```mvc routes``` request locals can be injected via ```@Local``` annotation: ## flash scope -The flash scope is designed to transport success and error messages, between requests. The flash scope is similar to [Session](#session) but lifecycle is shorter: *data are kept for only one request*. +The flash scope is designed to transport success and error messages between requests. It is similar to a [Session](#session) but the lifecycle is shorter: *data is kept for only one request*. -The flash scope is implemented as client side cookie, so it helps to keep application stateless. +The flash scope is implemented as a client side cookie, keeping the application stateless. ### usage @@ -440,13 +440,13 @@ import org.jooby.FlashScope; } ``` -[FlashScope]({{defdocs}}/FlashScope.html) is also available on mvc routes via [@Flash]({{defdocs}}/mvc/Flash.html) annotation: +The [FlashScope]({{defdocs}}/FlashScope.html) is also available on mvc routes via the [@Flash]({{defdocs}}/mvc/Flash.html) annotation: ```java @Path("/") public class Controller { - // Access to flashScope + // Access to the flashScope @GET public Object flashScope(@Flash Map flash) { ... @@ -466,7 +466,7 @@ public class Controller { } ``` -Worth to mention that flash attributes are accessible from template engine of your choice by prefixing flash attribute's name with ```flash.```. Here is a (handlebars.java)[/doc/hbs] example: +Flash attributes are accessible from templates by prefixing the attribute's name with ```flash.```. Here's a (handlebars.java)[/doc/hbs] example: ```html {{#if flash.success}} @@ -482,7 +482,7 @@ Worth to mention that flash attributes are accessible from template engine of yo The {{request}} object has access to the application [registry]({{defdocs}}/Registry.html) which give you access to application services. -Access to registry is available via: [request.require(type)]({{defdocs}}/Request.html#require-com.google.inject.Key-) methods: +Access to the registry is available via: [request.require(type)]({{defdocs}}/Request.html#require-com.google.inject.Key-) methods: ```java get("/", req -> { @@ -491,7 +491,7 @@ get("/", req -> { }); ``` -Of course the `require` method doesn't make sense on `MVC routes`, because you can inject dependencies: +Of course, the `require` method doesn't make sense on `MVC routes`, because in that case you can inject dependencies: ```java @Path("/") @@ -513,7 +513,7 @@ public class Controller { ## access log -Log all the matched incoming requested using the NCSA format (a.k.a common log format). +Log all matching incoming requests using the NCSA format (a.k.a common log format). ### usage @@ -552,7 +552,7 @@ You probably want to configure the ```RequestLog``` logger to save output into a ``` -Due that authentication is provided via module or custom filter, there is no concept of logged/authenticated user. Still you can log the current user by setting an user id provider at construction time: +Since authentication is provided via a module or custom filter, there is no concept of a logged in or authenticated user. You can still log the current user by setting a user id provider at construction time: ```java { @@ -570,13 +570,13 @@ Due that authentication is provided via module or custom filter, there is no con } ``` -Here an application filter set an ```userId``` request attribute and then we provide that ```userId``` to {@link RequestLogger}. +In this example, an application filter sets a ```userId``` request attribute and then that ```userId``` is provided to the {@link RequestLogger}. ### custom log function -By default it uses the underlying logging system: logback. That's why we previously show how to configure the ```org.jooby.RequestLogger``` in ```logback.xml```. +By default all logging uses logback which is why the ```org.jooby.RequestLogger``` was configured in ```logback.xml```. -If you want to log somewhere else and/or use a different technology then: +If you want to log somewhere else, or want to use a different logging implementation: ```java { @@ -587,7 +587,7 @@ If you want to log somewhere else and/or use a different technology then: } ``` -This is just an example but of course you can log the ```NCSA``` line to database, jms queue, etc... +Rather than printing the ```NCSA``` line to stdout, it can of course be written to a database, a JMS queue, etc. ### latency @@ -598,7 +598,7 @@ This is just an example but of course you can log the ```NCSA``` line to databas } ``` -It add a new entry at the end of the ```NCSA``` output that represents the number of ```ms``` it took to process the request. +This will append an entry at the end of the ```NCSA``` output representing the number of ```ms``` it took to process the request. ### extended @@ -624,9 +624,9 @@ Extend the ```NCSA``` by adding the ```Referer``` and ```User-Agent``` headers t } ``` -Override, the default formatter for the request arrival time defined by: [Request#timestamp()]({{defdocs}}/Request.html#timestamp----). You can provide a function or an instance of `DateTimeFormatter`. +Override the default formatter for the request arrival time defined by: [Request#timestamp()]({{defdocs}}/Request.html#timestamp----). You can provide a function or an instance of `DateTimeFormatter`. -The default formatter use the default server time zone, provided by `ZoneId#systemDefault()`. It's possible to just override the time zone too: +The default formatter uses the default server time zone, provided by `ZoneId#systemDefault()`. It's possible to simply override the time zone as well: ```java { diff --git a/md/route-attrs.md b/md/route-attrs.md index d77cd30f71..433bb1e858 100644 --- a/md/route-attrs.md +++ b/md/route-attrs.md @@ -8,7 +8,7 @@ Routes have a few properties that let you extend basic functionality in one way ### attributes -Attributes let you annotated a route at application bootstrap time. It is like static metadata available at runtime: +Attributes let you annotate a route at application bootstrap time. It functions like static metadata available at runtime: ```java { @@ -17,9 +17,9 @@ Attributes let you annotated a route at application bootstrap time. It is like s } ``` -An attribute consist of a `name` and `value`. Allowed values are ```primitives```, ```String```, ```enum```, ```class``` or an ```array``` of previous types. +An attribute consist of a `name` and `value`. Allowed values are ```primitives```, ```String```, ```enum```, ```class``` or an ```array``` of these types. -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... +Attributes can be accessed at runtime in a request/response cycle. For example, a security module might check for a ```role``` attribute, a sitemap generator might check for a ```priority``` attribute, etc. ```java { @@ -73,20 +73,20 @@ public class AdminResource { The previous example will print: ```{role = admin}```. -Any runtime annotation is automatically added it as route attribute. Following these rules: +Any runtime annotation is automatically added as route attributes following these rules: -* If the annotation has a ```value``` method, then we use the annotation's name as attribute name. -* Otherwise, we use the method name as attribute name. +* If the annotation has a ```value``` method, then we use the annotation's name as the attribute name. +* Otherwise, we use the method name as the attribute name. > **request attributes vs route attributes:** > -> Route attributes are created at bootstrap time they are global and once you set they won't change. +> Route attributes are created at bootstrap. They are global, and once set, they won't change. > -> While, request attributes are created in a request/response cycle. +> On the other hand, request attributes are created in a request/response cycle. ### with operator -The {{route_with}} operator set attributes, consumes/produces types, exclusions, etc.. to one or more routes: +The {{route_with}} operator sets attributes, consumes/produces types, exclusions, etc. to one or more routes: ```java { @@ -158,7 +158,7 @@ For example, the {{route_map}} operator will be silently ignored here: ### excludes -The {{route_excludes}} operator skip/ignore a route path match: +The {{route_excludes}} operator ignores what would otherwise have been a route path match: ```java { @@ -170,7 +170,7 @@ The {{route_excludes}} operator skip/ignore a route path match: ### consumes -The {{route_consumes}} operator indicates the expected input the route can handle. It is used will accepting requests. +The {{route_consumes}} operator indicates the type of input the route can handle. ```java { @@ -183,7 +183,7 @@ The {{route_consumes}} operator indicates the expected input the route can handl ### produces -The {{route_produces}} operator indicates the expected output the route can produces. +The {{route_produces}} operator indicates the type of output the route can produce. ```java { diff --git a/md/routes.md b/md/routes.md index b05ae52d68..6e92e520a6 100644 --- a/md/routes.md +++ b/md/routes.md @@ -1,17 +1,17 @@ # routes -A route describes the interface for making requests to your application. It combines a HTTP **method** and a **path pattern**. +A route describes the interface for making requests to your application. It combines an HTTP **method** and a **path pattern**. A route has an associated **handler**, which does some job and produces some kind of output (HTTP response). -Jooby offers two programming model for writing routes: +Jooby offers two programming models for writing routes: -* Script routes via **lambdas**, like *Sinatra* and/or *expressjs* -* MVC routes via **annotations**, like *Jersey* and/or *Spring* (covered later) +* Script routes via **lambdas**, like *Sinatra* or *expressjs* +* MVC routes via **annotations**, like *Jersey* or *Spring* (covered later) ## creating routes -A `script` route definition looks like: +A `script` route definition looks like this: ```java { @@ -19,7 +19,7 @@ A `script` route definition looks like: } ``` -while a `MVC` route definition looks like: +while an `MVC` route definition looks like this: ```java @@ -36,9 +36,9 @@ public class Controller { } ``` -MVC routes are [covered later](/doc/#routes-mvc-routes) in details. For simplicity and easy to understand all the example uses the `script` routes, but keep in mind you can do the same in `MVC` routes. +MVC routes are [covered later](/doc/#routes-mvc-routes) in detail. For simplicity, all the examples use `script` routes, but keep in mind you can do the same with `MVC` routes. -We created a route to handle a GET request at the root of our application. Any other HTTP method can be created in the same way. +A route was created to handle GET requests at the root of our application. Any other HTTP method can be handled the same way. If you need a `POST`: @@ -52,14 +52,14 @@ or need to listen to any `HTTP method`: use("*", "/", () -> "hey jooby"); ``` -It is possible to name a route explicitly: +It's also possible to name a route explicitly: ```java get("/", () -> "hey jooby") .name("salute"); ``` -Default route name is **anonymous**. Naming a route is useful for debugging purpose (if you have two or more routes mounted on the same path) and for [dynamic and advanced routing](#routes-dynamic-advanced-routing). +The default route name is **anonymous**. Naming a route is useful for debugging purposes (if you have two or more routes mounted on the same path) and for [dynamic and advanced routing](#routes-dynamic-advanced-routing). ## route handler @@ -71,7 +71,7 @@ Jooby offers several flavors for routes: get("/", () -> "hey jooby"); ``` -This handler usually produces a constant value. Returned value will be send to the client. +This handler usually produces a constant value. The returned value will be sent to the client. ### functional handler: req @@ -79,7 +79,7 @@ This handler usually produces a constant value. Returned value will be send to t get("/", req -> "hey " + req.param("name").value()); ``` -This handler depends on some `external` attribute which is available via [Request]({{defdocs}}/Request.html) object. Returned value will be send to the client. +This handler depends on some `external` attribute which is available via the [Request]({{defdocs}}/Request.html) object. The return value will be sent to the client. ### handler: (req, rsp) @@ -87,7 +87,7 @@ This handler depends on some `external` attribute which is available via [Reques get("/", (req, rsp) -> rsp.send("hey " + req.param("name").value()); ``` -This handler depends on some `external` attribute which is available via [Request]({{defdocs}}/Request.html) object and we explicitly send a response via [response.send]({{defdocs}}/Response.html#send(java.lang.Object)) method. +This handler depends on some `external` attribute which is available to the [Request]({{defdocs}}/Request.html) object and the response is explicitly sent via the [response.send]({{defdocs}}/Response.html#send(java.lang.Object)) method. ### filter: (req, rsp, chain) @@ -99,9 +99,9 @@ get("/", (req, rsp, chain) -> { }); ``` -This is the most advanced handler, you have access to the [Request]({{defdocs}}/Request.html), [Response]({{defdocs}}/Response.html) and [Route.Chain]({{defdocs}}/Route.Chain.html) objects. +This is the most advanced handler. You have access to the [Request]({{defdocs}}/Request.html), the [Response]({{defdocs}}/Response.html) and the [Route.Chain]({{defdocs}}/Route.Chain.html) objects. -From here you can end a response by calling [response.send]({{defdocs}}/Response.html#send(java.lang.Object)) method, abort the request by throwing an [Err]({{defdocs}}/Err.html) or allow to proceed to the next handler in the pipeline by calling [chain.next(req, rsp)]({{defdocs}}/Route.Chain.html#next-org.jooby.Request-org.jooby.Response-). +From a handler like this, it's possible to end a response by calling the [response.send]({{defdocs}}/Response.html#send(java.lang.Object)) method, abort the request by throwing an [Err]({{defdocs}}/Err.html) or allow the request to proceed to the next handler in the pipeline by calling [chain.next(req, rsp)]({{defdocs}}/Route.Chain.html#next-org.jooby.Request-org.jooby.Response-). ## path patterns @@ -123,14 +123,14 @@ get("/user/:id", req -> "hey " + req.param("id").value()); // alternative syntax get("/user/{id}", req -> "hey " + req.param("id").value()); -// matches path element with prefix "uid" +// matches a path element with the prefix "uid" get("/user/uid{id}", req -> "hey " + req.param("id").value()); // regex get("/user/{id:\\d+}", req -> "hey " + req.param("id").intValue()); ``` -Request parameters are covered later, for now all you need to know is that you can access to a path parameter using the [Request.param(String)]({{apidocs}}/org/jooby/Request.html#param(java.lang.String)). +Request parameters will be covered later. For now all you need to know is that you can access a path parameter using [Request.param(String)]({{apidocs}}/org/jooby/Request.html#param(java.lang.String)). ### ant style patterns @@ -177,7 +177,7 @@ GET /assets/js/index.js GET /assets/css/style.css ``` -It is possible to map a single static file to a path: +It's possible to map a single static file to a path: ```java { @@ -195,7 +195,7 @@ Here is another example with [webjars](http://www.webjars.org): } ``` -and responds to the following requests: +which would respond to the following requests: ``` GET /assets/jquery/2.1.3/jquery.js @@ -206,7 +206,7 @@ GET /assets/bootstrap/3.3.4/css/bootstrap.css By default the asset handler is able to read files from the `public` folder, which is a classpath folder. -It is possible to specify an `external` file system location too: +It's possible to specify an `external` file system location as well: ``` { @@ -224,7 +224,7 @@ The `assets.cache.maxAge` controls the `Cache-Control` header. Allowed value inc ### using a CDN -The asset handler goes one step forward and add support for serving files from a ```CDN``` out of the box. +The asset handler goes one step forward and adds support for serving files from a ```CDN``` out of the box. All you have to do is to define a ```assets.cdn``` property: @@ -243,12 +243,11 @@ A ```GET``` to ```/assets/js/index.js``` will be redirected to: ```http://d7471v ### assets module -There is also an awesome and powerful [assets](/doc/assets) module. The [assets](/doc/assets) -is library to validate, concatenate, minify or compress JavaScript and CSS assets. +There is also a powerful and all-round awesome [assets](/doc/assets) module. This module can validate, concatenate, minify or compress JavaScript and CSS assets. ## precedence and order -Routes are executed in the **order they are defined**. So the ordering of routes is crucial to the behavior of an application. Let's review this fact via some examples: +Routes are executed in the **order they are defined**. That means that the ordering of routes is crucial to the behavior of an application. Let's examine how this works with some examples: ```java get("/abc", req -> "first"); @@ -268,11 +267,11 @@ It produces a response of ```second```. > As you can see **ORDER IS VERY IMPORTANT**. -Now, why is it allowed to have two routes on the same path? +How come it's legal with two or more routes on the same path? -Because we want **filters** for routes. +Because this is how **filters** for routes are enabled. -A route handler accept a third parameter, commonly named chain, which refers to the next route handler in line: +A route handler accepts a third parameter, commonly named chain, which refers to the next route handler in line: ```java get("/abc", (req, rsp, chain) -> { @@ -285,17 +284,17 @@ get("/abc", (req, rsp) -> { }); ``` -Again the order of route definition is important. Forgetting this will cause your application behave unpredictably. We will learn more about this behavior in the examples of the next section. +Again the order of route definition is important. Forgetting this will cause your application behave unpredictably. You will learn more about this behavior in the examples in the next section. ## request handling -When a request is made to the server, which matches a route definition, the associated callback functions kick in to process the request and send back a response. We call this route pipe or stack. +When a request matching a route definition is made to the server, the associated callback functions kick in to process the request and send a response. This is called a route pipe or stack. -Routes are like a plumbing pipe, requests start at the first route you define and work their way "down" the route stack processing for each path they match. +Routes are like a plumbing pipe, with requests starting at the first route and then working their way "down" the route stack processing for each path they match. -Each route handler has the capability to send a response or pass on the request to the next route handler in the current stack. +Each route handler has the capability to send a response or pass the request on to the next route handler in the current stack. -Route handlers, also have access to the chain object, which happens to be the next callback function in the pipe. To make the chain object available to the callback function, pass it along with the req and the rsp objects to it: +Route handlers, also have access to the chain object, which happens to be the next callback function in the pipe. To make the chain object available to the callback function, pass it as a method parameter: ```java get("/", (req, rsp, chain) -> { @@ -303,7 +302,7 @@ get("/", (req, rsp, chain) -> { }); ``` -If there is no matching callback function after the current callback function, next refers to the built-in 404 error handler, and it will be triggered when you call it. +If there is no matching callback function after the current callback function, next refers to the built-in 404 error handler, and will be triggered when you call it. Try to guess the output of: @@ -317,9 +316,9 @@ get("/", (req, rsp) -> rsp.send("third")); Will the server print all of them? "first"? "third"? -It prints "first". The act of doing a {{rsp_send}} terminates the flow of the request then and there; the request is not passed on to any other route handler. +It prints "first". The act of doing a {{rsp_send}} will terminate the flow of the request then and there; the request is not passed on to any other route handler. -So, how do we specify multiple handlers for a route, and use them all at the same time? Call the {{chain_next}} function from the callback, without calling {{rsp_send}} because it terminates the request flow. Here is an example: +So, how can you specify multiple handlers for a route, and use them all at the same time? Call the {{chain_next}} function from the callback, without calling {{rsp_send}} (as that would terminate the request). Here is an example: ```java get("/", (req, rsp, chain) -> { @@ -339,7 +338,7 @@ get("/", (req, rsp) -> { ``` -Alternative, if you **always** call {{chain_next}} just use the `(req, rsp` handler: +Alternatively, if you **always** call {{chain_next}} just use the `(req, rsp` handler: ```java get("/", (req, rsp) -> { @@ -357,9 +356,9 @@ get("/", (req, rsp) -> { ``` -The 3rd arg is required if you need to decide if the next route need to be executed or not. If you always call {{chain_next}} the 3rd arg isn't required and does exactly what the 2arg handler does: **always** call {{chain_next}}. +The third argument is required if you need to decide whether the next route needs to be executed or not. If you always call {{chain_next}} the third argument isn't required and does exactly what the second argument handler does: it **always** calls {{chain_next}}. -A good example for a filter is to handle for example authentication: +A good example for a filter is to handle e.g. authentication: ```java get("/", (req, rsp, chain) -> { @@ -374,7 +373,7 @@ get("/", (req, rsp, chain) -> { ## content negotiation -A route can produces different results based on the ```Accept``` header: +A route can produce different results based on the ```Accept``` header: ```java get("/", () -> @@ -385,4 +384,4 @@ get("/", () -> ); ``` -Performs content-negotiation on the Accept HTTP header of the request object. It select a handler for the request, based on the acceptable types ordered by their quality values. If the header is not specified, the first callback is invoked. When no match is found, the server responds with ```406 Not Acceptable```, or invokes the default callback: ```**/*```. +This will perform content-negotiation on the Accept HTTP header of the request object. It selects a handler for the request, based on the acceptable types ordered by their quality factor. If the header is not specified, the first callback is invoked. When no match is found, the server responds with ```406 Not Acceptable```, or invokes the default callback: ```**/*```. diff --git a/md/rsp.md b/md/rsp.md index 9f30950963..2aa8beb56f 100644 --- a/md/rsp.md +++ b/md/rsp.md @@ -1,14 +1,14 @@ # response -The response object contains methods for reading and setting headers, status code and body (between others). In the next section we will mention the most important method of a response object, if you need more information please refer to the [javadoc]({{apidocs}}/org/jooby/Response.html). +The response object contains methods for reading and setting headers, status code and body (amongst other things). In the next section you will encounter the most important methods of the response object. If you need more information please refer to the [javadoc]({{apidocs}}/org/jooby/Response.html). ## send -The [rsp.send]({{defdocs}}/Response.html#send-org.jooby.Result-) method is responsible for sending and writing data into the HTTP Response. +The [rsp.send]({{defdocs}}/Response.html#send-org.jooby.Result-) method is responsible for sending and writing data into the HTTP response. A [renderer]({{defdocs}}/Renderer.html) is responsible for converting a Java Object into something else (json, html, etc..). -Let's see a simple example: +Let's consider a simple example: ```java get("/", (req, rsp) -> rsp.send("hey jooby")); @@ -18,9 +18,9 @@ get("/", req -> "hey jooby"); // or just return a value and Jooby will call send The **send** method will ask the [Renderer API]({{defdocs}}/Renderer.html) to format an object and write a response. -The resulting ```Content-Type``` when is not set is ```text/html```. +The resulting ```Content-Type``` when not set is ```text/html```. -The resulting ```Status Code``` when is not set is ```200```. +The resulting ```Status Code``` when not set is ```200```. Some examples: @@ -55,9 +55,9 @@ get("/", req -> { ## headers -Retrieval of response headers is done via [rsp.header("name")]({{defdocs}}/Response.html#header-java.lang.String-). The method always returns a [Mutant]({{defdocs}}/Mutant.html) and from there you can convert to any of the supported types. +Retrieval of response headers is done via [rsp.header("name")]({{defdocs}}/Response.html#header-java.lang.String-). This method returns a [Mutant]({{defdocs}}/Mutant.html) which can be converted to any of the supported types. -Setting a header is pretty straightforward too: +Setting a header is pretty straightforward as well: ```java rsp.header("Header-Name", value).header("Header2", value); @@ -65,7 +65,7 @@ rsp.header("Header-Name", value).header("Header2", value); ## send file -Send file API is available via [rsp.download*]({{defdocs}}/Response.html#download-java.lang.String-) methods: +The send file API is available through the [rsp.download*]({{defdocs}}/Response.html#download-java.lang.String-) methods: ```java { @@ -75,7 +75,7 @@ Send file API is available via [rsp.download*]({{defdocs}}/Response.html#downloa } ``` -The ```download``` method sets all these headers: +The ```download``` method sets the following headers: * ```Content-Disposition``` @@ -83,7 +83,7 @@ The ```download``` method sets all these headers: * ```Content-Type``` -In the next example we explicitly set some of these headers: +In the next example we explicitly set some of these: ```java { diff --git a/md/session.md b/md/session.md index 7de9f12550..6eb562d568 100644 --- a/md/session.md +++ b/md/session.md @@ -1,11 +1,11 @@ # session Sessions are created on demand via: [req.ifSession()]({{defdocs}}/Request.html#ifSession--) or [req.session()]({{defdocs}}/Request.html#session--). -Sessions have a lot of uses cases but most commons are: auth, store information about current +Sessions have a lot of uses cases but the most commons are: authentication, storing information about current user, etc. -A session attribute must be ```String``` or a primitive. Session doesn't allow to store -arbitrary objects. It is a simple mechanism to store basic data. +A session attribute must be a ```String``` or a primitive. The session doesn't allow storing of +arbitrary objects. It's intended as a simple mechanism to store basic data. ## usage @@ -23,7 +23,7 @@ arbitrary objects. It is a simple mechanism to store basic data. } ``` -Previous example will use an `in-memory` session. The next example uses a cookie: +The previous example will use an `in-memory` session. The next example uses a cookie: ```java { @@ -41,9 +41,9 @@ Previous example will use an `in-memory` session. The next example uses a cookie } ``` -The cookie session store depends on the `application.secret` property. We sign the cookie with the `application.secret` property. +The cookie session store depends on the `application.secret` property. The cookie will be signed with the value of this property. -If `memory` or `cookie` store are not an option, then you can choose one of the [high performance session store](/doc/session) provided by {{jooby}}. We provide session stores for `redis`, `memcached`, `mongodb`, `cassandra`, `couchbase`, `hazelcast` and [lot more](/doc/session). +As an alternative to the `memory` or the `cookie` stores, you can choose any one of the [high performance session stores](/doc/session) provided by {{jooby}}. There are provided session stores for `redis`, `memcached`, `mongodb`, `cassandra`, `couchbase`, `hazelcast` and [a lot more](/doc/session). ```java { @@ -63,10 +63,10 @@ If `memory` or `cookie` store are not an option, then you can choose one of the ## no timeout -There is no timeout for sessions from server perspective. By default, a session will expire when -the user close the browser (a.k.a session cookie) or the cookie session has expired via `maxAge` attribute. +There is no timeout for sessions from the perspective of the server. By default, a session will expire when +the user close the browser (a.k.a session cookie) or the cookie session has expired via the `maxAge` attribute. -Session store implementation might or might not implemented a server `timeout`. +Session store implementations might or might not implement a server `timeout`. ## cookie @@ -76,15 +76,15 @@ indicates that the cookie will expire after that many seconds have passed. Note the maximum age when the cookie will expire, not the cookie's current age. A negative value means that the cookie is not stored persistently and will be deleted when the -Web browser exits. +browser exits. Default maxAge is: -1. ### signed cookie -If the application.secret property has been set, then the session cookie will be -signed it with it. +If the application.secret property has been set, the session cookie will be +signed with it. -### cookie's name +### cookie name The session.cookie.name indicates the name of the cookie that hold the session ID, by -defaults: jooby.sid. Cookie's name can be explicitly set with +default: jooby.sid. The cookie's name can be explicitly set with [cookie.name("name")]({{defdocs}}/Cookie.Definition.html#name-java.lang.String-) on [Session.Definition#cookie()]({{defdocs}}/Session.Definition.html#cookie). diff --git a/md/spec.md b/md/spec.md index b23597e45d..a8406089ff 100644 --- a/md/spec.md +++ b/md/spec.md @@ -1,16 +1,16 @@ The spec module allows you to export your API/microservices outside a {{jooby}} application. -The goal of this module is to define a common way to write APIs and provide you tools like live doc and testing **with no extra effort**. +The goal of this module is to define a common way to write APIs and provide tools like live doc and testing **with no extra effort**. -> You aren't force to learn any other tool or annotated your code special annotations. All you have to do is **write your application** following a few/minor suggestions. +> You won't be forced to learn any other tool or annotate your code with special annotations. All you have to do is **write your application** following a few simple suggestions. -This module process, collect and compile **routes** from your application. It extracts HTTP method/pattern, parameter, responses, types and doc. +This module will process, collect and compile **routes** from your application. It extracts HTTP method, path patterns, parameters, response types and documentation. -You will find here the basis and the necessary documentation to build and expose rich APIs for free, but keep in mind this module isn't intended for direct usage. It is the basis for tools like {{swagger}} or {{raml}}. +You will find the basics and the necessary documentation to build and expose rich APIs for free, but keep in mind that this module isn't intended to be used directly. It is the base for tools like {{swagger}} or {{raml}}. # definition -Let's review how to build rich APIs using the ```spec``` module via ```script``` or ```mvc``` way: +Let's review how to build rich APIs using the ```spec``` module using either the ```script``` or the ```mvc``` programming styles: ## script API @@ -171,7 +171,7 @@ public class Pets { } ``` -Previous examples are feature identical, but they were written in very different way. Still API Spec for them look likes: +The previous examples, while feature identical, are written very differently. The API Spec for both is still the same: ```yaml @@ -248,17 +248,17 @@ DELETE /api/pets/:id doc: A 204 ``` -> NOTE: We use ```textual``` representation here for simplicity and easy read, but keep in mind the output is compiled into a binary format. +> NOTE: We use a ```textual``` representation here for simplicity and readability, but keep in mind that the output is compiled into a binary format. ## script rules -Have a look at the previous examples again? Do you see anything special? No, right? +Consider the previous examples again. Do you notice anything special? No, right? -Well there are some minor things you need to keep in mind for getting or collecting route metadata from **script** routes: +There are however some minor issues that you need to keep in mind for getting or collecting route metadata from **script** routes: ### params -Params need to be in one sentence/statement, like: +Parameters need to be in one sentence/statement, like: ```java req -> { @@ -277,7 +277,7 @@ req -> { ### response type (a.k.a return type) -There should be **ONLY one** return statement and return type needs to be declared as variable, like: +There should be **ONLY one** return statement and the return type needs to be declared as a variable, like this: ```java req -> { @@ -288,7 +288,7 @@ req -> { } ``` -not like: +not like this: ```java req -> { @@ -311,13 +311,13 @@ req -> { } ``` -There is a workaround if these rules doesn't make sense to you and/or the algorithm fails to resolve the correct type. Please checkout next section. +If these rules don't make sense to you or if the algorithm fails to resolve the correct type, there is a workaround outlined in the next section. -## writing doc +## writing documentation -If you take a few minutes and write good quality doc the prize will be huge! +By taking a few minutes to write quality documentation for your code, you will reap huge benefits! -The tool takes and export the doc as part of your API!! +The spec tool will export the doc as part of your API! Here is an example on how to document script routes: @@ -390,25 +390,25 @@ response: doc: Returns 200 with a single pet or 404 ``` -Here you tell the tool response is a ```Pet``` via *JavaDoc* type references: ```{@link Type}```. +In this example you tell the spec tool that the response is a ```Pet``` via *JavaDoc* type references: ```{@link Type}```. -This is useful when the tool isn't able to detect the type for you and/or you aren't able to follow the return rules described before. +This is useful when the tool isn't able to detect the type for you and/or you aren't able to follow the return rules described earlier. -The status codes section have a ```200``` and ```404``` entries with default messages. You can override the default message by using ```code = message``` like: +The status codes section has entries for ```200``` and ```404``` with default messages. You can override the default message by using ```code = message``` like: ```html @return Returns a {@link Pet} with 200 = Success status or 404 = Missing ``` -## how it works? +## how does it work? -The spec module scan and parse the source code: ```*.java``` and produces a list of ```RouteSpec```. +The spec module scans and parses the source code files: ```*.java``` and produces a list of ```RouteSpec```. -It is required for getting information from ```script routes``` and extract ```JavaDoc```. +This is required for getting information from ```script routes``` and to extract ```JavaDoc```. -We don't need that for ```mvc routes``` because all the information is available via *Reflection* and ```java.lang.Method```. +However, this is not needed for ```mvc routes``` because all the information is available through *Reflection* and the ```java.lang.Method```. -So, the tool needs the source code in order to work properly. In order to use the tool at deploy time you must to setup the ```jooby:spec``` maven plugin: +Since the spec tool needs the source code in order to work properly you must set up the ```jooby:spec``` maven plugin in order to use the spec tool at deploy time: ```xml @@ -443,6 +443,6 @@ apply plugin: 'jooby' gradle joobySpec ``` -The maven/gradle plugin exports the API into a binary format: ```.spec``` which can be parse it later. +The maven and gradle plugins export the API to a binary format: ```.spec``` which can be parsed at a later time. -That's all about the spec, as you see there are some minor rules to follow while writing ```script routes```. Now it's time see what tools and integrations are available!!! +That's all about the spec, as you've seen there are some minor rules to follow while writing ```script routes```. Now it's time see what tools and integrations are available! diff --git a/md/sse.md b/md/sse.md index 8c99452fd6..62d8bc465e 100644 --- a/md/sse.md +++ b/md/sse.md @@ -1,6 +1,6 @@ # server-sent events -Server-Sent Events (SSE) is a mechanism that allows server to push the data from the server to the client once the client-server connection is established by the client. Once the connection is established by the client, it is the server who provides the data and decides to send it to the client whenever new **chunk** of data is available. +[Server-Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events) (SSE) is a mechanism that allows the server to push data to the client once the client-server connection is established. After the connection has been established by the client, the server can send to the client whenever a new **chunk** of data is available. In contrast with websockets, SSE can only be used to send from the server to the client and not the other way round. ## usage @@ -15,9 +15,9 @@ Server-Sent Events (SSE) is a mechanism that allows server to push the data from } ``` -Simple, effective and easy to use. The callback will be executed when a new client is connected. Inside the callback we can send data, listen for connection close events, etc. +Simple, effective and easy to use. The callback will be executed when a new client is connected. Inside the callback you can send data, listen for connection close events, etc. -There is a factory method [sse.event(Object)]({{apidocs}}/org/jooby/Sse.html#event-java.lang.Object-) that let you set event attributes: +The factory method [sse.event(Object)]({{apidocs}}/org/jooby/Sse.html#event-java.lang.Object-) will let you set event attributes: ```java { @@ -35,9 +35,9 @@ There is a factory method [sse.event(Object)]({{apidocs}}/org/jooby/Sse.html#eve ## structured data -Beside raw/string data you can also send structured data, like ```json```, ```xml```, etc.. +Other than raw/string data you can also send structured data, like ```json```, ```xml```, etc.. -The next example will send two message one in ```json``` format and one in ```text/plain``` format: +The next example will send two messages, one in ```json``` format and one in ```text/plain``` format: ```java { @@ -68,7 +68,7 @@ Or if your need only one format, just: ## request parameters -We provide request access via **two arguments** callback: +Request access is provided by a **two argument** callback: ```java { @@ -84,7 +84,7 @@ We provide request access via **two arguments** callback: ## connection lost -The [sse.onClose(Runnable)]({{apidocs}}/org/jooby/Sse.html#onClose-javaslang.control.Try.CheckedRunnable-) callback allow you to clean and release resources on connection close. A connection is closed when you call [sse.close()]({{apidocs}}/org/jooby/Sse.html#close--) method or the client/browser close the connection. +The [sse.onClose(Runnable)]({{apidocs}}/org/jooby/Sse.html#onClose-javaslang.control.Try.CheckedRunnable-) callback allows you to clean and release resources on connection close. A connection is closed when you call the [sse.close()]({{apidocs}}/org/jooby/Sse.html#close--) method or when the remote client closes the connection. ```java { @@ -114,13 +114,13 @@ The keep alive time feature can be used to prevent connections from timing out: } ``` -The previous example will sent a ```':'``` message (empty comment) every 15 seconds to keep the connection alive. If the client drop the connection, then the [sse.onClose(Runnable)]({{apidocs}}/org/jooby/Sse.html#onClose-javaslang.control.Try.CheckedRunnable-) event will be fired it. +The previous example will send a ```':'``` message (empty comment) every 15 seconds to keep the connection alive. If the client drops the connection, then the [sse.onClose(Runnable)]({{apidocs}}/org/jooby/Sse.html#onClose-javaslang.control.Try.CheckedRunnable-) event will be fired. -This feature is useful when you want to detect close events without waiting for the next time you send an event. But for example, if your application already generate events every 15s, then the use of keep alive is useless and you can avoid it. +This feature is useful when you want to detect close events without waiting for the next time you send an event. If on the other hand your application already generates events every 15 seconds, the use of keep alive is unnecessary. ## require -The [sse.require(Type)]({{apidocs}}/org/jooby/Sse.html#require-java.lang.Class-) methods let you access to application services: +The [sse.require(Type)]({{apidocs}}/org/jooby/Sse.html#require-java.lang.Class-) methods gives you access to application services: ```java { @@ -134,7 +134,7 @@ The [sse.require(Type)]({{apidocs}}/org/jooby/Sse.html#require-java.lang.Class-) ## example -The next example will generate a new event every 60s. It recovers from a server shutdown by using the [sse.lastEventId()]({{apidocs}}/org/jooby/Sse.html#lastEventId--) and clean resources on connection close. +The next example will generate a new event every 60 seconds. It recovers from a server shutdown by using the [sse.lastEventId()]({{apidocs}}/org/jooby/Sse.html#lastEventId--) and cleans resources on connection close. ```java { diff --git a/md/stork.md b/md/stork.md index cc66ce01e6..1c5635e2f4 100644 --- a/md/stork.md +++ b/md/stork.md @@ -26,7 +26,7 @@ Maven properties defined here will be resolved and merged into the final output. ## example -Here is a simple example of the ```stork.yml``` launcher: +Here's a simple example of the ```stork.yml``` launcher: ```yml # Name of application (make sure it has no spaces) diff --git a/md/tests.md b/md/tests.md index a80bbbd688..81a93d369a 100644 --- a/md/tests.md +++ b/md/tests.md @@ -1,19 +1,19 @@ # tests -In this section we are going to see how to run unit and integration tests in Jooby. +This section will show you how to run unit and integration tests with Jooby. ## unit tests -We do offer two programming models: +There are two available programming models: -* script programming model; and -* mvc programming model +* the script programming model; and +* the mvc programming model -You don't need much for ```MVC``` routes, because a route is binded to a method of some class. So it is usually very easy and simple to mock and run unit tests against a ```MVC``` route. +Testing ```MVC``` routes is pretty straightforward since a route is bound to a method of some class. This makes it simple to mock and run unit tests against these kinds of routes. -We can't say the same for ```script``` routes, because a route is represented by a ```lambda``` and there is no easy or simple way to get access to the lambda object. +To test ```script``` routes is more involved since a route is represented by a ```lambda``` and there is no easy or simple way to get access to the lambda object. -We do provide a [MockRouter]({{defdocs}}/mvc/MockRouter.html) which simplify unit tests for ```script routes```: +For this reason there's a [MockRouter]({{defdocs}}/mvc/MockRouter.html) provided to simplify unit testing of ```script routes```: ### usage @@ -73,7 +73,7 @@ public void shouldGetRequestPath() { } ``` -You can mock a [Response]({{defdocs}}/Response.html) object in the same way: +You can mock a [Response]({{defdocs}}/Response.html) object similarly: ```java { @@ -106,7 +106,7 @@ public void shouldUseResponseSend() { } ``` -What about external dependencies? It works in a similar way: +What about external dependencies? This is handled similarly: ```java { @@ -137,11 +137,11 @@ public void shouldMockExternalDependencies() { } ``` -The [MockRouter#set(Object)]({{defdocs}}/mvc/MockRouter.html#set-java.lang.Object-) call push and register an external dependency (usually a mock). This make it possible to resolve services from ```require``` calls. +The [MockRouter#set(Object)]({{defdocs}}/mvc/MockRouter.html#set-java.lang.Object-) calls push and will register an external dependency (usually a mock). This makes it possible to resolve services from ```require``` calls. ### deferred -Mock of promises are possible too: +Mocking of promises is possible as well: ```java { @@ -162,7 +162,7 @@ public void shouldMockPromises() { } ``` -Previous test works for deferred routes: +The previous test works for deferred routes: ```java { @@ -177,7 +177,7 @@ Previous test works for deferred routes: Integration tests are possible thanks to a [JUnit Rule](https://github.com/junit-team/junit4/wiki/Rules). -You can choose between `@ClassRule` or `@Rule`. The next example uses `ClassRule`: +You can choose between `@ClassRule` or `@Rule`. The following example uses `ClassRule`: ```java @@ -191,9 +191,9 @@ public class MyIntegrationTest { } ``` -Here **one** and **only one** instance will be created, which means the application start before the first test and stop after the last test. Application state is **shared** between tests. +Here **one** and **only one** instance will be created, which means the application will start before the first test and stop after the last test. Application state is **shared** between tests. -While with `Rule` a new application is created per test. If you have N test, then the application will start/stop N times: +With `Rule` on the other hand, a new application is created per test. If you have N tests, the application will start and stop N times: ```java @@ -206,7 +206,7 @@ public class MyIntegrationTest { } ``` -Again you are free to choice the HTTP client of your choice, like [Fluent Apache HTTP client](https://hc.apache.org/httpcomponents-client-ga/tutorial/html/fluent.html), [REST Assured](https://github.com/rest-assured/rest-assured), etc.. +Again you are free to select the HTTP client of your choice, like [Fluent Apache HTTP client](https://hc.apache.org/httpcomponents-client-ga/tutorial/html/fluent.html), [REST Assured](https://github.com/rest-assured/rest-assured), etc. Here is a full example with [REST Assured](https://github.com/rest-assured/rest-assured): diff --git a/md/war.md b/md/war.md index d0e1e313ed..53956a6a0b 100644 --- a/md/war.md +++ b/md/war.md @@ -1,11 +1,11 @@ This module exists for strict environments where the ONLY option is to deploy into a Servlet Container. -If you are free to deploy a new server technology, we strongly recommend to avoid this and go directly with {{netty}}, {{jetty}} or {{undertow}}. +It's strongly recommended to avoid this and rather opt for using one of {{netty}}, {{jetty}} or {{undertow}}. ## usage -In order to deploy into a Servlet Container, we need to generate a ```*.war``` file. The next steps guide you on how to do it: +In order to deploy into a Servlet Container, you need to generate a ```*.war``` file. Here's how: -* Write a ```war.activator``` file inside the ```src/etc``` directory. +* Create a ```war.activator``` file in the ```src/etc``` directory. * Open a console and type: ```mvn clean package``` @@ -23,7 +23,7 @@ In order to deploy into a Servlet Container, we need to generate a ```*.war``` f ### special note on contextPath -To avoid a headache... make sure to use the ```contextPath``` variable while loading static/dynamic +To avoid potential headaches, make sure to use the ```contextPath``` variable while loading static/dynamic resources (.css, .js, etc..). For example: @@ -37,18 +37,18 @@ For example: ``` -Here the expression: ```{{contextPath}}``` corresponds to the template engine (handlebars here) or ```${contextPath}``` for Freemarker. +The expression: ```{{contextPath}}``` corresponds to the template engine (handlebars in that case) or ```${contextPath}``` for Freemarker. -## how it works? +## how does it work? -The presence of the ```src/etc/war.activator``` file triggers a Maven profile. Content of the file doesn't matter, just the presence. +The presence of the ```src/etc/war.activator``` file triggers a Maven profile. The contents of the file doesn't matter, it just needs to be present. -The Maven profile build the ```*.war``` file using the ```maven-assembly-plugin```. The assembly descriptor can be found +The Maven profile builds the ```*.war``` file using the ```maven-assembly-plugin```. The assembly descriptor can be found [here](https://github.com/jooby-project/jooby/blob/master/jooby-dist/src/main/resources/assemblies/jooby.war.xml) ### web.xml -A default ```web.xml``` file is generated by the assembly plugin. File looks like: +A default ```web.xml``` file is generated by the assembly plugin. This file looks like: ```xml @@ -83,9 +83,9 @@ A default ```web.xml``` file is generated by the assembly plugin. File looks lik ``` -#### upload size +#### max upload size -Default upload size is set to ```204800b``` (200kb). If you need to increase the upload size, add +The default max upload size is set to ```204800b``` (200kb). If you need to increase this, add the ```war.maxRequestSize``` property to ```pom.xml```: ```xml diff --git a/md/web-sockets.md b/md/web-sockets.md index c2d11bffab..eb27cfe280 100644 --- a/md/web-sockets.md +++ b/md/web-sockets.md @@ -12,25 +12,25 @@ } ``` -A [web socket]({{defdocs}}/WebSocket.html) consist of a **path pattern** and a [handler]({{defdocs}}/WebSocket.Handler.html). +A [WebSocket]({{defdocs}}/WebSocket.html) consists of a **path pattern** and a [handler]({{defdocs}}/WebSocket.Handler.html). -A **path pattern** can be as simple or complex as you need. All the path patterns supported by routes are supported here. +A **path pattern** can be as simple or complex as you need. All the path patterns supported by routes are supported. -The [onOpen]({{defdocs}}/WebSocket.OnOpen.html) listener is executed on new connections, from there we can listen for message, errors and/or send data to the client. +The [onOpen]({{defdocs}}/WebSocket.OnOpen.html) listener is executed on new connections, from there it's possible to listen for messages and errors or to send data to the client. -Keep in mind that **web socket** are not like routes. There is no stack/pipe or chain. +Keep in mind that a **WebSocket** is different from a route. There is no stack/pipe or chain. -You can mount a socket to a path used by a route, but you can't have two or more web sockets under the same path. +You can mount a socket to a path used by a route, but you can't have two or more WebSockets under the same path. ## send and broadcast -As you saw early a [web socket]({{defdocs}}/WebSocket.html) and send data to client via [ws.send(...)]({{defdocs}}/WebSocket.html#send-java.lang.Object-) method. +As seen earlier, a [web socket]({{defdocs}}/WebSocket.html) can send data to the client via the [ws.send(...)]({{defdocs}}/WebSocket.html#send-java.lang.Object-) method. -The [ws.broadcast(...)]({{defdocs}}/WebSocket.html#broadcast-java.lang.Object-) method does the same thing but for all the connected clients. +The [ws.broadcast(...)]({{defdocs}}/WebSocket.html#broadcast-java.lang.Object-) method does the same thing, but will send to all connected clients. ## require -Access to existing services is provided via [ws.require(type)]({{defdocs}}/WebSocket.html#require-com.google.inject.Key-) method: +Access to existing services is provided through the [ws.require(type)]({{defdocs}}/WebSocket.html#require-com.google.inject.Key-) method: ```java ws("/", ws -> { @@ -40,7 +40,7 @@ ws("/", ws -> { ## listener -As with **routes** we do provide **two flavors** for `WebSockets`: +As with **routes** you can choose between **two flavors** for `WebSocket` listeners: script: @@ -85,11 +85,11 @@ class MyHandler implements WebSocket.OnMessage { } ``` -Optionally, your listener could implements [onOpen]({{defdocs}}/WebSocket.OnOpen.html), [onClose]({{defdocs}}/WebSocket.OnClose.html) or [onError]({{defdocs}}/WebSocket.OnError.html). If you need them all then use [handler]({{defdocs}}/WebSocket.Handler.html) interface. +Optionally, your listener could implement [onOpen]({{defdocs}}/WebSocket.OnOpen.html), [onClose]({{defdocs}}/WebSocket.OnClose.html) or [onError]({{defdocs}}/WebSocket.OnError.html). If you need all of them, use the [handler]({{defdocs}}/WebSocket.Handler.html) interface. ## consumes -Web socket can define a type to consume: +A WebSocket can define a type to consume: ```java { @@ -117,11 +117,11 @@ class MyHandler implements WebSocket.OnMessage { } ``` -This is just an utility method for parsing socket message to Java Object. Consumes in web sockets has nothing to do with content negotiation. Content negotiation is route concept, it doesn't apply for web sockets. +This is just a utility method for parsing a socket message into a Java Object. Consumes in WebSockets has nothing to do with content negotiation. Content negotiation is a route concept, it doesn't apply for WebSockets. ## produces -Web socket can define a type to produce: +A WebSocket can define a type to produce: ```java { @@ -147,4 +147,4 @@ class MyHandler implements WebSocket.OnMessage { } ``` -This is just an utility method for formatting Java Objects as text message. Produces in web sockets has nothing to do with content negotiation. Content negotiation is route concept, it doesn't apply for web sockets. +This is just a utility method for formatting Java Objects as text messages. Produces in WebSockets has nothing to do with content negotiation. Content negotiation is a route concept, it doesn't apply for WebSockets. diff --git a/md/working-with-data.md b/md/working-with-data.md index ad4365501f..a5ca436353 100644 --- a/md/working-with-data.md +++ b/md/working-with-data.md @@ -2,7 +2,7 @@ ## parser -A [Parser]({{defdocs}}/Parser.html) is responsible for parsing the HTTP params and/or body to something else. +A [Parser]({{defdocs}}/Parser.html) is responsible for parsing the HTTP parameters or body to something else. Automatic type conversion is provided when a type: @@ -13,12 +13,12 @@ Automatic type conversion is provided when a type: * Has a static method **valueOf** that accepts a single **String** argument * Has a static method **fromString** that accepts a single **String** argument. Like ```java.util.UUID``` * Has a static method **forName** that accepts a single **String** argument. Like ```java.nio.charset.Charset``` -* It is an Optional, List, Set or SortedSet where T satisfies one of previous rules +* Is an Optional, List, Set or SortedSet where T satisfies one of previous rules ### custom parser -Suppose we want to write a custom parser to convert a value into an ```integer```. In practice we don't need such parser bc it is provided, this is an example. +Suppose you want to write a custom parser to convert a value into an ```integer```. In practice you won't need a parser like that since it's already provided, this is just an example. Let's see how to create our custom HTTP param parser: @@ -43,13 +43,13 @@ get("/", req -> { Let's have a closer look: -1) Check if current type is what we can parse to +1) Check if current type matches our target type -2) We add a param callback +2) Add a param callback -3) We can't deal with current type, so we ask next parser to resolve it +3) Can't deal with current type, ask the next parser to resolve it -Now, if we ask for HTTP body +Now, when asking for the HTTP body: ```java get("/", req -> { @@ -59,7 +59,7 @@ get("/", req -> { ``` -Our custom parser won't be able to parse the HTTP body, because it works on HTTP parameter. In order to extend our custom parser and use it for HTTP Body we must do: +The custom parser won't be able to parse the HTTP body, since it only works on HTTP parameters. In order to extend the custom parser and use it for the HTTP body: ```java @@ -76,7 +76,7 @@ parser((type, ctx) -> { ``` -And now we can ask for a HTTP param and/or body. +Now it's possible to ask for a HTTP param and/or body: ```java get("/", req -> { @@ -90,7 +90,7 @@ post("/", req -> { }); ``` -[Parser]({{defdocs}}/Parser.html) API is very powerful. It let you apply a parser to a HTTP param, set of param (like a form post), file uploads and/or body. But not just that, you are free to choose if your parser applies for a Java Type and/or a Media Type, like the ```Content-Type``` header. +The [parser]({{defdocs}}/Parser.html) API is very powerful. It lets you apply a parser to a HTTP parameter, set of parameters (like a form post), file uploads or a body. You are also free to choose if your parser applies for a Java Type and/or a Media Type, like the ```Content-Type``` header. For example a generic JSON parser looks like: @@ -106,13 +106,13 @@ parser((type, ctx) -> { Parsers are executed in the order they are defined. -If a param parser isn't able to resolve a param a ```BAD REQUEST(400)``` error will be generated. +If a parameter parser isn't able to resolve a parameter a ```BAD REQUEST(400)``` error will be generated. -If a body parser isn't able to resolve a param an ```UNSUPPORTED_MEDIA_TYPE(415)``` error will be generated. +If a body parser isn't able to resolve a parameter an ```UNSUPPORTED_MEDIA_TYPE(415)``` error will be generated. ## renderer -A [Renderer]({{defdocs}}/Renderer.html) converts a Java Object to a series of bytes or text and write them into the HTTP response. +A [Renderer]({{defdocs}}/Renderer.html) converts a Java Object to a series of bytes or text and writes them to the HTTP response. There are a few built-in renderers: @@ -124,7 +124,7 @@ There are a few built-in renderers: ### custom renderer -Suppose we want to apply a custom rendering for ```MyObject```. Renderer is as simple as: +Suppose you want to apply custom rendering for ```MyObject```. The renderer is as simple as: ```java @@ -139,7 +139,7 @@ get("/", req -> { }); ``` -A generic JSON renderer will looks like: +A generic JSON renderer will look like: ```java @@ -156,13 +156,13 @@ get("/", req -> { }); ``` -Renderer API is simple and powerful. Renderers are executed in the order they were defined. The renderer who write the response first wins! +The renderer API is simple and powerful. Renderers are executed in the order they were defined. The renderer which writes the response first wins! ## view engine -A [view engine]({{defdocs}}/View.Engine.html) is a specialized [renderer]({{defdocs}}/Renderer.html) that ONLY accept instances of a [view]({{defdocs}}/View.html). +A [view engine]({{defdocs}}/View.Engine.html) is a specialized [renderer]({{defdocs}}/Renderer.html) that ONLY accepts instances of a [view]({{defdocs}}/View.html). -A [view]({{defdocs}}/View.html) carry the template name + model data: +A [view]({{defdocs}}/View.html) carries the template name + model data: ```java { @@ -173,6 +173,6 @@ A [view]({{defdocs}}/View.html) carry the template name + model data: } ``` -In order to support multiples view engine, a view engine is allowed to throw a ```java.io.FileNotFoundException``` when a template can't be resolved it. This gives the chance to the next view resolver to load the template. +In order to support multiple view engines, a view engine is allowed to throw a ```java.io.FileNotFoundException``` when it's unable to resolve a template. This passes control to the next view resolver giving it a chance to load the template. -There is no much to say about views and template engines, any other detail or documentation should be provided in the specific [module](/doc/parser-and-renderer) +There's not much more to say about views and template engines, further details and documentation is provided in the specific [module](/doc/parser-and-renderer). diff --git a/md/xss.md b/md/xss.md index 05898e3346..85cc0bfb17 100644 --- a/md/xss.md +++ b/md/xss.md @@ -1,18 +1,18 @@ ## xss -[Cross-site scripting (XSS)](https://en.wikipedia.org/wiki/Cross-site_scripting) is a type of computer security vulnerability typically found in web applications. XSS enables attackers to inject client-side scripts into web pages viewed by other users. +[Cross-site scripting (XSS)](https://en.wikipedia.org/wiki/Cross-site_scripting) is a type of security vulnerability typically found in web applications. XSS enables attackers to inject client-side scripts into web pages viewed by other users. {{Jooby}} provides a few XSS escapers and a simple and flexible way to provide custom and/or more featured XSS escapers. -Default XSS escapers are `urlFragment`, `formParam`, `pathSegment` and `html` all them from [Guava](https://github.com/google/guava). +Default XSS escapers are `urlFragment`, `formParam`, `pathSegment` and `html`, all provided by [Guava](https://github.com/google/guava). -More advanced/featured escapers like `js`, `css`, `sql` are provided via [modules](/doc/security). +More advanced and feature rich escapers like `js`, `css`, `sql` are provided via [modules](/doc/security). ### usage -There are a few way of using XSS escape functions: +There are a couple of ways to use XSS escape functions: -#### Applying a XSS escaper to `param` or `header`: +#### Applying an XSS escaper to `param` or `header`: ```java { @@ -36,7 +36,7 @@ Here `input` is the `param/header` that you want to escape with the `html` escap } ``` -#### Applying a XSS escaper to form/bean: +#### Applying an XSS escaper to form/bean: ```java { @@ -46,9 +46,9 @@ Here `input` is the `param/header` that you want to escape with the `html` escap } ``` -#### Applying a XSS escaper from template engines +#### Applying an XSS escaper from template engines -Template engines usually provide a way to escape `HTML` (mainly) ... still {{jooby}} integrates XSS escapers with the template engine of your choice: +Template engines usually provide built in methods to escape `HTML`. However, {{jooby}} will also integrate its XSS escapers with the template engine of your choice: [handlebars](/doc/hbs): From d10c3dc21d6ab91f47c47f1a910ea8885fb63698 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20J=C3=B8rgen=20Hoel?= Date: Wed, 12 Apr 2017 14:13:36 +0200 Subject: [PATCH 3/3] More language changes for docs --- md/guides/jdbi.md | 30 +++++++++++++++--------------- md/quickstart.md | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/md/guides/jdbi.md b/md/guides/jdbi.md index 384d23eb44..9a14cbdd2f 100644 --- a/md/guides/jdbi.md +++ b/md/guides/jdbi.md @@ -1,13 +1,13 @@ {{#unless website}}[![Build Status](https://travis-ci.org/jooby-guides/{{guide}}.svg?branch=master)](https://travis-ci.org/jooby-guides/{{guide}}){{/unless}} # jdbi guide -In this guide you will learn how to build a **JSON API** for ```Pets``` and persist them into a **relational database** using {{modlink "jdbi"}} module. +In this guide you will learn how to build a **JSON API** for ```Pets``` and persist them into a **relational database** using the {{modlink "jdbi"}} module. -[JDBI](http://jdbi.org/) is a SQL convenience library for Java. It attempts to expose relational database access in idiommatic Java, using collections, beans, and so on, while maintaining the same level of detail as JDBC. It exposes two different style APIs, a fluent style and a sql object style. +[JDBI](http://jdbi.org/) is a SQL convenience library for Java. It attempts to expose relational database access in idiomatic Java, using collections, beans, and so on, while maintaining the same level of detail as JDBC. It exposes two different style APIs, a fluent style and a sql object style. # requirements -Make sure you have all these software installed it in your computer: +Make sure you have the following installed on your computer: * A text editor or IDE * {{java}} or later @@ -21,7 +21,7 @@ Open a terminal/console and paste: mvn archetype:generate -B -DgroupId={{pkgguide}} -DartifactId={{guide}} -Dversion=1.0 -DarchetypeArtifactId=jooby-archetype -DarchetypeGroupId=org.jooby -DarchetypeVersion={{version}} ``` -Jump into the application: +Enter the application directory: ``` cd {{guide}} @@ -41,7 +41,7 @@ Add the {{modlink "jackson"}} dependency to your project: ``` -Got to `App.java` and add the module: +Go to `App.java` and add the module: ```java import org.jooby.json.Jackson; @@ -101,7 +101,7 @@ The ```mem``` or ```fs``` are special databases. In order to use them we need th ``` -> **NOTE**: If you want to connect to `mySQL` database (or any other), then you'll have to add the ```mySQL Java Driver``` to your project and define the connection properties like: +> **NOTE**: If you want to connect to a database other than the embedded ```mem``` or ```fs```, like e.g. `mySQL`, then you'll have to add the ```mySQL Java Driver``` to your project and define the connection properties like this: > > ``` > db.url = "jdbc:mysql//localhost/pets" @@ -113,7 +113,7 @@ The ```mem``` or ```fs``` are special databases. In order to use them we need th We are going to create a database schema at application startup time: -* Define a `schema` property in ```conf/application.conf``` like: +* Define a `schema` property in ```conf/application.conf``` like this: ``` schema = """ @@ -160,7 +160,7 @@ With a database ready, we are going to build our *JSON API*. ## creating a repository -[The SQL Object API](http://jdbi.org/sql_object_overview/) provides a declarative mechanism for a common [JDBI](http://jdbi.org/) usage – creation of DAO type objects where one method generally equates to one SQL statement. To use the SQL Object API, create an interface annotated to declare the desired behavior, like so: +[The SQL Object API](http://jdbi.org/sql_object_overview/) provides a declarative mechanism for a common [JDBI](http://jdbi.org/) usage – creation of DAO type objects where one method generally equates to one SQL statement. To use the SQL Object API, create an interface annotated to declare the desired behavior, like this: ```java {{source "PetRepository.java"}} @@ -222,7 +222,7 @@ You'll see an error page because we didn't persist any pet yet. Let's see how to ## save a pet -So far, we see how to query pets by ID or listing all them, it is time to see how to creates a new pet: +So far, we've seen how to query pets by ID or listing all them, it is time to see how to create a new pet: ```java { @@ -291,7 +291,7 @@ So far, we see how to query pets by ID or listing all them, it is time to see ho # quick preview -API is ready, let's see how it looks like: +The API is ready, let's see how it looks like: ```java { @@ -332,9 +332,9 @@ API is ready, let's see how it looks like: } ``` -Not bad, ugh? +Not bad, huh? -Isn't, but did you see we have to repeat the `/api/pets` pattern for each of our routes? +But did you notice that we have to repeat the `/api/pets` pattern for each of our routes? Let's fix that with {{javadoc "Jooby" "use" "java.lang.String"}}: @@ -342,12 +342,12 @@ Let's fix that with {{javadoc "Jooby" "use" "java.lang.String"}}: {{source mainclass}} ``` -Better now! The ```use``` method has many meanings in **Jooby**, If we use pass a ```String``` we can group route under a same path pattern. +That's better! The ```use``` method has many meanings in **Jooby**, If we use pass a ```String``` we can group routes under the same path pattern. # conclusion -As you already see, building an API that saves data in a **database** is very simple. Code looks clean and simple thanks to {{modlink "jdbi"}} module. +As you've already seen, building an API that saves data in a **database** is very easy. The code looks clean and simple thanks to the {{modlink "jdbi"}} module. -The {{modlink "jdbi"}} module makes perfect sense if you want to have full control on your SQL queries, or if you don't like **ORM** tools too. +The {{modlink "jdbi"}} module makes perfect sense if you want to have full control of your SQL queries, or if you prefer not to use **ORM** tools. {{> guides/guide.footer}} diff --git a/md/quickstart.md b/md/quickstart.md index 736f10aec2..e069c26f2d 100644 --- a/md/quickstart.md +++ b/md/quickstart.md @@ -52,7 +52,7 @@ getting started exploring the newly created project ----- -A new directory was created: ```my-app```. Let's see how it looks like: +A new directory was created: ```my-app```. Let's see what it looks like: ```bash .