Cette page rassemble les correspondances API et les pièges typiques pour migrer un service HTTP existant vers Chappe. Pour les chiffres de performance comparés, voir lien:https://codeberg.org/Vidocq/chappe/blob/main/BENCH.md[BENCH.md].

Chappe est en 0.1.0-SNAPSHOT. Une migration de production est prématurée. La table ci-dessous documente le mapping API ; valider chaque cas d’usage avec les tests d’intégration de votre service avant de basculer.

Vue d’ensemble

Diagram

Depuis Jetty

Jetty Chappe Note

Server + ServerConnector

Server.builder().port(…​).build()

Plus serré ; pas de connecteur séparé.

ServletContextHandler

Foy sur Chappe

Servlet via le pont Foy.

org.eclipse.jetty.util.thread.QueuedThreadPool

Executors.newVirtualThreadPerTaskExecutor() (par défaut)

Pas de pool plateforme ; pas de tuning.

Handler.Sequence

Composition Filter#andThen

Modèle plus simple, sans nextHandler().

ResourceHandler

StaticFileHandler.builder().addPath(…​).build()

cacheInMemory(true) côté Chappe pour le classpath.

GzipHandler

Filter.gzip() ou sidecars pré-compressés

Skip auto si Cache-Control: no-transform ou MIME non text-like.

Depuis Netty

Netty Chappe Note

EventLoopGroup

Virtual threads

Pas de boucle d’événements applicative.

ChannelInitializer / ChannelPipeline

Pas d’équivalent direct

Composer via Filter et Router. Pour un protocole binaire custom, Chappe n’est pas le bon outil.

ChannelHandler

Handler (lambda)

Modèle synchrone — Loom le rend équivalent en scalabilité.

ByteBuf

Body (InputStream / OutputStream)

Pas de pool de buffers exposé à l’utilisateur. Le ByteBufferPool de chappe-http est interne.

HttpServerCodec + HttpObjectAggregator

Inclus de base

Parsing HTTP/1.1 et HTTP/2 dans chappe-http.

Migrer un pipeline Netty complexe (par exemple un proxy multi-protocoles avec backpressure custom) est un chantier sérieux. Chappe ne réplique pas l’extensibilité bas niveau de Netty au niveau channel. Si vous écrivez votre propre protocole binaire ou avez besoin d’un contrôle fin du backpressure côté écriture, Chappe n’est probablement pas le bon outil.

Depuis Undertow

Undertow Chappe Note

Undertow.builder().addHttpListener(port, host)

Server.builder().port(port).bindAddress(host)

API equivalente.

RoutingHandler

Router.builder()

API fluide, mêmes verbes.

ResourceHandler

StaticFileHandler

Fallback chain filesystem → classpath natif.

BlockingHandler wrapper

Inutile

Tous les handlers Chappe sont synchrones bloquants sur virtual thread.

XnioWorker threads

Virtual threads

Pas de tuning de pool.

HttpString cache

Headers internes

ArrayHeaders zero-alloc sur le hot path.

Depuis JDK 25 HttpServer

com.sun.net.httpserver.HttpServer est minimal et n’est pas pensé pour la production. Avantage : sans dépendance. Désavantages : pas de HTTP/2, pas de virtual threads par défaut, multiplexage limité.

JDK HttpServer Chappe Note

HttpServer.create(addr, backlog)

Server.builder().port(…​).bindAddress(…​).build()

Builder fluide.

createContext("/path", handler)

Router.builder().get("/path", req → …​).build()

Match par méthode + path, pas seulement par préfixe.

HttpHandler#handle(HttpExchange)

Handler#handle(Request) → Response

Fonction pure ; pas d’accès direct à la socket.

setExecutor(Executors.newVirtualThreadPerTaskExecutor())

Par défaut

Aucun setup.

Migration vers la CLI standalone

Si votre besoin est seulement « servir un site statique en production » (cas Docker), basculer le launcher Java vers chappe serve :

java \
     -jar chappe-cli/target/chappe-cli-*-shaded.jar \
     serve --root /var/www/site --port 8080 --gzip

Configuration via YAML, headers conditionnels par variable d’environnement, sidecars .gz au build via le plugin Maven. Voir Référence — CLI chappe serve.

Points de bascule typiques

Fonction existante Bascule Chappe

Logger HTTP access (Tomcat, Jetty RequestLog)

Filter custom qui écrit sur System.Logger ou java.util.logging. Chappe n’embarque pas de logger.

Compression Brotli runtime

Non supportée. Sidecars .br produits au build (pipeline externe), servis si Accept-Encoding: br.

WebSocket

Planifié — voir lien:https://codeberg.org/Vidocq/chappe/blob/main/BUG.md[BUG.md].

Servlet API complète

Foy sur Chappe (Jakarta Servlet 6.1).

JAX-RS / REST

Cassini sur Chappe (Jakarta REST 4.0).

TLS PEM natif

Non supporté côté Chappe. Convertir en PKCS12 avec openssl ou keytool, puis charger via KeyStore.

Capacits prtes pour la migration

  • CLI standalone (chappe serve --config …) — packaging Docker direct, image jlink ~50 Mo.

  • Filter.gzip() + StaticFileHandler.preferPrecompressed(true) — compression ngocie + sidecars .br / .gz.

  • StaticFileHandler.spaFallback("/index.html") / .notFoundFile("/404.html") — routing SPA et 404 personnalisée.

  • Filter.addHeaderIfEnv("STAGING", "true", "X-Robots-Tag", "noindex, nofollow") — headers conditionnels par environnement.

  • Router.mount(prefix, handler) — composition d’extensions Servlet/REST sans couplage.