Module.web
Duct module for running web applications
Install / Use
/learn @duct-framework/Module.webREADME
Duct module.web 
A Duct module that adds a web server and useful middleware to a configuration. This is the basis of all web applications built with Duct.
This current version is experimental and will only work with the new
duct.main tool. The artifact group name has been changed to prevent
accidental upgrades. The version prior to this change was: 0.7.4.
Installation
Add the following dependency to your deps.edn file:
org.duct-framework/module.web {:mvn/version "0.13.4"}
Or to your Leiningen project file:
[org.duct-framework/module.web "0.13.4"]
Usage
To add this module to your configuration, add a reference to
:duct.module/web:
{:duct.module/web {}}
To change how the module behaves, you can supply a set of :features.
A feature is one of the following keywords:
:api- add middleware and handlers suitable for a web service:hiccup- add middleware to automatically parse Hiccup responses:site- add middleware and handlers suitable for a user-facing web application
Multiple features may be added.
By default, the module uses the Reitit Ring router. This is
available via the :duct.router/reitit key. For example:
{:duct.module/web {:features #{:site}}
:duct.router/reitit {:routes [["/" #ig/ref :app.example/handler]]}}
:app.example/handler {}
You can also use the :routes key on the module:
{:duct.module/web
{:features #{:site}
:routes [["/" #ig/ref :app.example/handler]]}
:app.example/handler {}}
This will automatically add appropriate refs and handler keys, so the above configuration can be written:
{:duct.module/web
{:features #{:site}
:routes [["/" :app.example/handler]]}}
It may be the case that you want all handlers to have a common configuration,
such as providing a reference to a database. You do this easily with the
:handler-opts key, which merges a supplied options map with the options for
all the handlers referenced in the routes.
For example:
{:duct.database/sql {:jdbcUrl "jdbc:sqlite:"}
:duct.module/web
{:features #{:site}
:handler-opts {:db #ig/ref duct.database/sql}
:routes [["/" :app.example/handler]]}}
Middleware can be added in one of three ways:
- Via the top-level
:middlewarekey - Via the top-level
:route-middlewarekey - Via a
:middlewarekey on a route options map
All these keys take a vector of middleware definitions:
{:middleware
[#ig/ref :eg/middleware1 ;; an Integrant ref
:eg/middleware2 ;; a namespaced keyword that will be turned into a ref
[:eg/middleware3 :arg]} ;; middleware with an extra argument
Like routes, a corresponding definition will be automatically added for each middleware reference.
The top-level :middleware option will add middleware to the whole
handler, regardless of whether any route matches.
The top-level :route-middleware option will add middleware if and only
if a route matches.
The per-route :middleware key will add middleware only to that route.
You can also use the :middleware-opts function to automatically add
common options to middleware, in the same way that :handler-opts
works.
License
Copyright © 2025 James Reeves
Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.
Related Skills
node-connect
351.8kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
110.9kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
351.8kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
351.8kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
