HelidonHelidon4.5.0

Server

Helidon MicroProfile Server

Overview

Helidon provides a MicroProfile server implementation (io.helidon.microprofile.server.Server) that encapsulates the Helidon WebServer.

Maven-Coordinates

To enable MicroProfile Server add the helidon-microprofile-core bundle dependency to your project’s pom.xml (see Managing Dependencies).

pom.xml
<dependency>
  <groupId>io.helidon.microprofile.bundles</groupId>
  <artifactId>helidon-microprofile-core</artifactId>
</dependency>

MicroProfile Server is already included in the bundle.

If full control over the dependencies is required, and you want to minimize the quantity of the dependencies - Helidon MicroProfile Server should be used. In this case the following dependencies should be included in your project’s pom.xml:

pom.xml
<dependency>
  <groupId>io.helidon.microprofile.server</groupId>
  <artifactId>helidon-microprofile-server</artifactId>
</dependency>

Usage

Helidon MicroProfile Server is used to collect and deploy JAX-RS application(s). When starting Helidon MP, it is recommended to use the io.helidon.Main main class, which will take care of starting Helidon. CDI will then discover all extensions, including the Server extension and start it.

See the Helidon MP Quickstart example. Note that the server lifecycle is bound to CDI.

Usage of the io.helidon.microprofile.server.Server API is discouraged, as Helidon MP uses convention to discover and configure features, which makes the applications easier to understand and maintain.

API

The following table provides a brief description of routing annotations, including its parameters.

See More information in the HttpService section.

AnnotationDescription
@RoutingName(value = "", required = false)
Binds a JAX-RS Application or Helidon Service to a specific (named) routing on WebServer. The routing should have a corresponding named socket configured on the WebServer to run the routing on.
@RoutingPath("/path")
Path of a Helidon Service to register with routing.

Configuration options

By default, the server uses the MicroProfile Config, but you may also want to use Helidon configuration.

In this example, the configuration is in a file, and it includes Helidon configuration options.

Configuration reference:

KeyTypeDefaultDescription
restore-response-headersBooleantrueCopy and restore response headers before and after passing a request to Jersey for processing
concurrency-limitLimitConcurrency limit to use to limit concurrent execution of incoming requests
content-encodingContentEncodingContextConfigure the listener specific io.helidon.http.encoding.ContentEncodingContext
media-contextMediaContextConfigure the listener specific io.helidon.http.media.MediaContext
max-payload-sizeLong⁠-⁠1Maximal number of bytes an entity may have
featuresList<ServerFeature>Server features allow customization of the server, listeners, or routings
use-nioBooleantrueIf set to true, use NIO socket channel, instead of a socket
protocols-discover-servicesBooleantrueWhether to enable automatic service discovery for protocols
enable-proxy-protocolBooleanfalseEnable proxy protocol support for this socket
hostString0.0.0.0Host of the default socket
write-queue-lengthInteger0Number of buffers queued for write operations
socketsMap<String, ListenerConfig>Socket configurations
protocolsList<ProtocolConfig>Configuration of protocols
max-tcp-connectionsInteger⁠-⁠1Limits the number of connections that can be opened at a single point in time
bind-addressStringThe address to bind to
idle-connection-timeoutDurationPT5MHow long should we wait before closing a connection that has no traffic on it
shutdown-grace-periodDurationPT0.5SGrace period in ISO 8601 duration format to allow running tasks to complete before listener's shutdown
max-concurrent-requestsInteger⁠-⁠1Limits the number of requests that can be executed at the same time (the number of active virtual threads of requests)
features-discover-servicesBooleantrueWhether to enable automatic service discovery for features
shutdown-hookBooleantrueWhen true the webserver registers a shutdown hook with the JVM Runtime
error-handlingErrorHandlingConfiguration for this listener's error handling
concurrency-limit-discover-servicesBooleanfalseWhether to enable automatic service discovery for concurrency-limit
backlogInteger1024Accept backlog
max-in-memory-entityInteger131072If the entity is expected to be smaller that this number of bytes, it would be buffered in memory to optimize performance when writing it
ignore-invalid-named-routingBooleanIf set to true, any named routing configured that does not have an associated named listener will NOT cause an exception to be thrown (default behavior is to throw an exception)
smart-async-writesBooleanfalseIf enabled and #writeQueueLength() is greater than 1, then start with async writes but possibly switch to sync writes if async queue size is always below a certain threshold
connection-optionsSocketOptionsOptions for connections accepted by this listener
portInteger0Port of the default socket
requested-uri-discoveryRequestedUriDiscoveryContextRequested URI discovery context
idle-connection-periodDurationPT2MHow often should we check for #idleConnectionTimeout()
nameString@defaultName of this socket
tlsTlsListener TLS configuration
write-buffer-sizeInteger4096Initial buffer size in bytes of java.io.BufferedOutputStream created internally to write data to a socket connection

Deprecated Options

KeyTypeDescription
connection-configConnectionConfigConfiguration of a connection (established from client against our server)
receive-buffer-sizeIntegerListener receive buffer size

Access Log

Access logging in Helidon is done by a dedicated module that can be added to Maven and configured.

To enable Access logging add the following dependency to project’s pom.xml:

pom.xml
<dependency>
  <groupId>io.helidon.microprofile</groupId>
  <artifactId>helidon-microprofile-access-log</artifactId>
</dependency>

Configuration options

KeyTypeDefaultDescription
formatStringThe format for log entries (similar to the Apache LogFormat)
logger-nameStringio.helidon.webserver.AccessLogName of the logger used to obtain access log logger from System#getLogger(String)
weightDouble1000.0Weight of the access log feature
socketsList<String>List of sockets to register this feature on
enabledBooleantrueWhether this feature will be enabled

Configuration Example

microprofile-config.properties
server.port=8080
server.host=0.0.0.0
server.features.access-log.format=helidon

TLS

Helidon MP also supports custom TLS configuration.

You can set the following properties:

  • Server truststore
    • Keystore with trusted certificates
  • Private key and certificate
    • Server certificate which will be used in TLS handshake

Server configuration:

microprofile-config.properties
#Truststore setup
server.tls.trust.keystore.resource.resource-path=server.p12
server.tls.trust.keystore.passphrase=password
server.tls.trust.keystore.trust-store=true

#Keystore with private key and server certificate
server.tls.private-key.keystore.resource.resource-path=server.p12
server.tls.private-key.keystore.passphrase=password

Or the same configuration done in application.yaml file.

Server configuration:

application.yaml
server:
  tls:
    #Truststore setup
    trust:
      keystore:
        passphrase: "password"
        trust-store: true
        resource:
          # load from classpath
          resource-path: "keystore.p12"1
    #Keystore with private key and server certificate
    private-key:
      keystore:
        passphrase: "password"
        resource:
          # load from file system
          path: "/path/to/keystore.p12"2
  1. File loaded from the classpath.
  2. File loaded from the file system.

Additional Ports

Helidon MP can expose multiple ports, with the following limitations:

  • The default port is the port that serves your application (JAX-RS applications and resources)
  • Other ports (in this example we configure one "admin" port) can be assigned endpoints that are exposed by Helidon components, currently supported by MP Health and MP Metrics

You can set the configuration in either application.yaml or META-INF/microprofile-config.properties:

  • The port 7011 is the default port and will serve your application
  • The port 8011 is named "admin" (this is an arbitrary name)
  • Observability endpoints, such as metrics and health, use the "admin" port through the features.observe.sockets setting.

Server configuration using application.yaml:

application.yaml
server:
  port: 7011
  host: "localhost"
  sockets:
    admin:
      port: 8011
      bind-address: "localhost"
  features:
    observe:
      sockets: "admin"

Server configuration using META-INF/microprofile-config.properties:

microprofile-config.properties
server.port=7011
server.host=localhost
server.sockets.0.name=admin
server.sockets.0.port=8011
server.sockets.0.bind-address=localhost
server.features.observe.sockets=admin

HTTPService

Helidon MP Server will pick up CDI beans that implement the io.helidon.webserver.HttpService interface and configure them with the underlying WebServer.

This allows configuration of WebServer 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.

The service can be customized using annotations and/or configuration to be

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

Helidon has the concept of named routing. These correspond to the named ports configured with WebServer.

You can assign an HTTP 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).

@RoutingName

You can annotate a service bean with this annotation to assign it to a specific named routing.

The annotation has two attributes:

  • value that defines the routing name
  • required to mark that the routing name MUST be configured
AdminService.java
@ApplicationScoped
@RoutingName(value = "admin", required = true)
@RoutingPath("/admin")
public class AdminService implements HttpService {
    @Override
    public void routing(HttpRules rules) {
        // ...
    }
}

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

Configuration Override

For each service bean you can define the routing name and its required flag by specifying a configuration option bean-class-name.routing-name.name and bean-class-name.routing-name.required. For service beans produced with producer method replace bean-class-name with class-name.producer-method-name.

Example (YAML) configuration for a service bean 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

@RoutingPath

You can configure @RoutingPath to define the path a service is registered on. 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)

Configuration Override

For each HTTP service class you can define the routing path by specifying a configuration option class-name.routing-path.path. The routing-path configuration can be applied to Jax-RS application. See Jakarta REST Application for more information.

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"

Static Content

File system static content:

microprofile-config.properties
# Location of content on file system
server.features.static-content.path.0.location=/var/www/html
# default is index.html (only in Helidon MicroProfile)
server.features.static-content.path.0.welcome=resource.html
# static content context on webserver - default is "/"
# server.features.static-content.path.0.context=/static-file

Classpath static content:

microprofile-config.properties
# src/main/resources/WEB in your source tree
server.features.static-content.classpath.0.location=/WEB
# default is index.html
server.features.static-content.classpath.0.welcome=resource.html
# static content path - default is "/"
# server.features.static-content.classpath.0.context=/static-cp

It is usually easier to configure list-based options using application.yaml instead, such as:

Static content:

application.yaml
server:
  features:
    static-content:
      welcome: "welcome.html"
      classpath:
        - context: "/static"
          location: "/WEB"
      path:
        - context: "/static-file"
          location: "./static-content"

See Static Content Feature Configuration Reference for details. The only difference is that we set welcome file to index.html by default.

Root re-direct

To redirect requests for the root path (/) to another path you can use the server.base-path property:

server:
  base-path: /static/index.html

For any HTTP request for / this will return a 301 with the Location: header set to the value of server.base-path. This is often used with Static Content Support to serve a specific index.html when / is requested.

Note that this feature is not for setting a context root for applications. To configure alternate context roots see Setting Application Path.

Configuration Example

A full configuration example (YAML):

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

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

Requested URI Discovery

Proxies and reverse proxies between an HTTP client and your Helidon application mask important information (for example Host header, originating IP address, protocol) about the request the client sent. Fortunately, many of these intermediary network nodes set or update either the standard HTTP Forwarded header or the non-standard X-Forwarded-* family of headers to preserve information about the original client request.

Helidon’s requested URI discovery feature allows your application and Helidon itself to reconstruct information about the original request using the Forwarded header and the X-Forwarded-* family of headers.

When you prepare the connections in your server you can include the following optional requested URI discovery settings:

  • enabled or disabled
  • which type or types of requested URI discovery to use:
    • FORWARDED - uses the Forwarded header
    • X_FORWARDED - uses the X-Forwarded-* headers
    • HOST - uses the Host header
  • what intermediate nodes to trust

When your application receives a request Helidon iterates through the discovery types you set up for the receiving connection, gathering information from the corresponding header(s) for that type. If the request does not have the corresponding header(s), or your settings do not trust the intermediate nodes reflected in those headers, then Helidon tries the next discovery type you set up. Helidon uses the HOST discovery type if you do not set up discovery yourself or if, for a particular request, it cannot assemble the request information using any discovery type you did set up for the socket.

Setting Up Requested URI Discovery

You can use configuration to set up the requested URI discovery behavior.

Configuring Request URI Discovery (properties format):

server.port=8080
server.requested-uri-discovery.types=FORWARDED,X_FORWARDED
server.requested-uri-discovery.trusted-proxies.allow.pattern=lb.*\\.mycorp\\.com
server.requested-uri-discovery.trusted-proxies.deny.exact=lbtest.mycorp.com

This example might apply if mycorp.com had trusted load balancers named lbxxx.mycorp.com except for an untrusted test load balancer lbtest.mycorp.com.

Obtaining the Requested URI Information

Helidon makes the requested URI information available as a property in the request context:

Retrieving Requested URI Information:

public class MyFilter implements ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext requestContext) {
        UriInfo uriInfo = (UriInfo) requestContext.getProperty("io.helidon.jaxrs.requested-uri");
        // ...
    }
}

See the UriInfo Javadoc for more information.

The requestContext.getUriInfo() method returns the Jakarta RESTful web services UriInfo object, not the Helidon-provided requested URI information UriInfo record.

Reference

Copyright © 2018, 2026 Oracle and/or its affiliates.