The preferred approach is to add routes for resources to your application.
(ns org.example.service
(:require [io.pedestal.http :as http]
[io.pedestal.http.resources :as resources]
[io.pedestal.http.route :as route]))
(defn create-server
[]
(http/create-server
{::http/port 8890
::http/type :jetty
::http/join? false
::http/routes (route/routes-from
#{ ... } (1)
(resources/file-routes {:file-root "web/public"}))})) (2)
1 | This is where you would put the dynamic routes for your application. |
2 | This exposes any files stored in the web/public folder under the default URI path /public . |
The routes-from
macro will expand and combine the routes together to form the full routing table.
The api:resource-routes[] function is analogous to file-routes
, but returns routes that expose resources on the classpath.
Each of these functions take a single parameter, a map of options:
Table 1. Options to file and resource functionsOption | Default | Only | Description |
---|
:prefix | "/public" | | The path prefix for the exposed resources. |
:root-path | - | file | Path to root directory to expose. |
:resource-root | - | resource | Prefix on resources, limiting access to a safe subset of the classpath |
:classloader | - | resource | Classloader used to find resources |
:index-files? | true | file | If true, paths that map to directories may return the index file for that directory. |
:cache? | true | | If true, then resource data is cached to in memory to speed up requests. |
:fast? | true | | If true, then fast, asynchronous responses may be used. |
:allow-head? | true | | If true, then additional routes are added to support the :head request method,
returning empty bodies. |
:route-namespace | "io.pedestal.http.resources" | | Namespace used when creating route names for the routes. |
Using the defaults, which enable fast responses and caching, the route-based resources are demonstrably faster
than the interceptor-based resources, especially for large resources … though
for any reasonably sized resource, the response time is sub-millisecond.
It is quite possible to use both file
and resource
together, as long as the :prefix is set so that routes do not overlap.
If necessary, it’s even possible to use these functions multiple times, but care must be taken with the :route-namespace to avoid
route name collisions.
The :prefix option should start with a "/" and not end with one.
For the :index-files? option, Pedestal will identify requests that map to a directory, not to a specific file.
Pedestal will search for one of the following:
-
index.html
-
index.htm
-
Any file whose name starts with index.
If any of these are found, then the request is treated as if it were to the matching file.
The :resource-root option should not start or end with a slash; to restrict access to just classpath files within the org.example.myapp.public
namespace, the option should be "org/example/myapp/public".
Requests that include any use of ".." in the path (in order to "escape" from the root location) are rejected, resulting in a 404 response.
The :cache? option does not currently put an upper limit on how many resources get cached; it’s presumed that there are only a finite number of resources that can be exposed and cached.
|
You will want to disable the :cache? option if you have more than a handful of resources that may be
available, as there’s no facility to access or clear the cache. If you have many hundreds of
resources, or the resources may change over time, caching is not a good option. You may want
to implement your own cache as an
interceptor around the resource routes.
|
The :fast? option will attempt to convert matched files or resources into a java.nio.channel.Channel instance, for an asynchronous response.
This only occurs if the size of the resource exceeds the buffer size of the servlet response.
The default used when the :classloader option is nil is the context class loader associated with the current thread.
Finally, the options map will also be passed to
api:table-routes[ns=io.pedestal.http.route.definition.table], so you may use the keys it
supports, particularly :scheme, :port, and :interceptors.