///////////////////////////////////////////////////////////////////////////////

    Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

///////////////////////////////////////////////////////////////////////////////

= Reactive routing in Helidon MP
:description: Helidon MP reactive routing
= :keywords: helidon, rest, reactive, WebServer, route, routing

Since Helidon 1.4

== Configuring a reactive route in Helidon MP
Helidon MP Server will pick up CDI beans that implement the `io.helidon.webserver.Service`
interface and configure them with the underlying WebServer.

This allows configuration of reactive routes to run alongside a JAX-RS application.

The bean is expected to be either `ApplicationScoped` or `Dependent` and will be requested
only once during the boot of the `Server`.

The bean will support injection of `ApplicationScoped` and `Dependent` scoped beans.
You cannot inject `RequestScoped` beans. Please use WebServer features to handle request
related objects.

=== Customizing the reactive service
The service can be customized using annotations and/or configuration to be

- registered on a specific path
- registered with a named routing

==== Assigning a reactive service to named ports
Helidon has the concept of named routings. These correspond to the named ports
configured with WebServer.

You can assign a reactive service to a named routing (and as a result to a named port) using
either an annotation or configuration (or both to override the value from annotation).

===== Annotation `@RoutingName`
You can annotated a service with this annotation to assign it to a specific named routing,
that is (most likely) going to be bound to a specific port.

The annotation has two attributes:
- `value` that defines the routing name
- `required` to mark that the routing name MUST be configured in Helidon server

Example:
----
@ApplicationScoped
@RoutingName(value="admin", required="true")
@RoutingPath("/admin")
public class AdminService implements Service {
//....
}
----

The example above will be bound to `admin` routing (and port) and will fail if such a port
is not configured.

===== Configuration override of routing name
For each service class you can define the routing name and its required flag by specifying a configuration
option `class-name.routing-name.name` and `class-name.routing-name.required`.

Example (YAML) configuration for a class `io.helidon.examples.AdminService` that changes the
routing name to `management` and its required flag to `false`:

----
io.helidon.examples.AdminService:
  routing-name:
    name: "management"
    required: false
----

==== Configuring a reactive service path
Each service is registered on a path. If none is configured, then the service would be
configured on the root path.

You can configure service path using an annotation or configuration (or both to override value from annotation)

===== Annotation `@RoutingPath`
You can configure `@RoutingPath` to define the path a service is registered on.

===== Configuration override of routing path
For each reactive service class you can define the routing path by specifying a configuration
option `class-name.routing-path.path`.

Example (YAML) configuration for a class `io.helidon.example.AdminService` that changes the
routing path to `/management`:

----
io.helidon.examples.AdminService:
  routing-path:
    path: "/management"
----

=== Example configuration of reactive service
A full configuration example (YAML):

----
server:
  port: 8080
  sockets:
    management:
      port: 8090

io.helidon.examples.AdminService:
  routing-name:
    name: "management"
    required: true
  routing-path:
    path: "/management"
----