NOTE: Whenever upgrading versions of Pedestal, please be sure to clean your project's out
or target
directory.
The main focus of this release is to improve routing.
BREAKING CHANGES:
- Many APIs deprecated in Pedestal 0.7.0 have been removed outright
- The
io.pedestal/pedestal.service-tools
library has been removed - Significant changes to io.pedestal.http.route have occured
- A new router, io.pedestal.http.route.sawtooth, has been added
- Sawtooth identfies conflicting routes
- Sawtooth is now the default router
Other changes:
- Table routes may now specify :interceptors (in the options map); these are prefixed on any interceptors provided by the route
Changes:
- Correctly detect when a response can not be returned due to the client disconnecting
Changes:
- Correctly report the tracing span status: PR
This release marks significant improvements to Pedestal, while laying the cornerstones for further improvements. The primary focus has been upgrading from Jetty 9 to Jetty 11 (and from Servlet API 3.1 to 5); much additional effort has been invested in improving the developer experience, rewriting support for application observability, enhancements to performance, deprecation of unused (or unsupported) code, as well as an intense focus on documentation improvements.
Although this release does include unavoidable breaking changes, we hope that for most applications, the upgrade process will be as simple as changing the version number. Applications that made direct use of Jetty APIs, or servlet APIs (using the javax.servlet namespace), will require additional scrutiny to upgrade, as will applications that make extensive use of the (now deprecated) observability functions provided by the io.pedestal/pedestal.log library.
BREAKING CHANGES:
- Library pedestal.jetty has been upgraded from Jetty 9 to Jetty 11
- Library pedestal.immutant has been removed
- Library pedestal.tomcat has been removed
- Library pedestal.aws has been removed
- Namespace
io.pedestal.http.jetty.websockets
has been removed, and replaced withio.pedestal.http.websockets
- Namespace
io.pedestal.interceptor.error
has been moved to a new library, io.pedestal/pedestal.error - Library pedestal.service no longer has a dependency on org.clojure/core.match; the new pedestal.error library has that dependency
- Interceptors that attach an invalid :response value (not a map, for example) will now cause an exception to be thrown
- Interceptors may now attach a partial :response map, containing just a :status key
Other changes:
- When using
io.pedestal.http/dev-interceptors
, uncaught exceptions are now formatted using org.clj-commons/pretty in the response sent to the client - Pedestal is now compatible with Clojure 1.10.1 and above
- In
io.pedestal.interceptor.chain
:- New macros
bind
andunbind
make it easier for interceptors to manipulate dynamic variables exposed to following interceptors - New function
on-enter-async
is used to register a callback invoked when execution first goes asynchronous - New function
queue
is used to peek at what interceptors remain on the queue - New function
add-observer
to add a callback after each interceptor executes in each stage
- New macros
- New function
io.pedestal.interceptor.chain.debug/debug-observer
to observe and log changes to the context made by interceptors - New function
io.pedestal.http/enable-debug-interceptor-observer
to setupdebug-observer
- New service map keys have been introduced:
- Support handling of uncaught exceptions
- May now specify an initial context map
- May now specify an interceptor responsible for request tracing
- There is now a clojure.spec specification for the structure of the service map, and for the structure of the different route specifications and the expanded routing table
- Added a deps-new template, io.pedestal/embedded, for creating a new Pedestal project around embedded Jetty
- Use of many deprecated functions and macros now cause deprecation warnings to be printed to stderr
- Metrics and tracing have been reimplemented from the ground up around Open Telemetry
- Libraries pedestal.log and pedestal.error contain clj-kondo configuration files to inform clj-kondo about their macros
- New function
io.pedestal.http/respond-with
to streamline adding a :response to the interceptor context - Easier application configuration: logger, metrics, and tracing configuration can occur inside a
pedestal-config.edn
file (orpedestal-test-config.edn
for tests), as well as via JVM system properties and environment variables - Improvements to REPL-based development, including printing the expanded routing table at startup (when in development mode)
This release is just to provide dependency upgrades to address CVEs in Jetty and Clojure.
A change has been made to the path-params-decoder
to address the breaking change in 0.6.0; by
making the decoder idempotent, it is no longer a breaking change.
Upgrade dependencies to fix CVEs in Jetty.
Upgrade dependencies to fix CVEs:
- aws-java-sdk-xray
- jetty (various)
- tomcat-embed-jasper & tomcat-embed-core
BREAKING CHANGES:
- Path parameters (extracted during routing) are now, by default, URL decoded (via
io.pedestal.http.route/path-params-decoder
), when usingio.pedestal.http/default-interceptors
; previously this was the application's responsibility, usually in individual routes' interceptor lists. The prior behavior can be restored by passing:io.pedestal.http/path-params-decoder
as nil in the service map provided toio.pedestal.http/create-server
. - Pedestal now requires JDK 11 or later
Other changes:
- Pedestal is now built using deps (
deps.edn
) rather than Leiningen (project.clj
) - Updated many dependencies, particularly to address CVEs in dependencies
- Improvements to documentation and examples
- Address critical dependency vulnerabilities (i.e., Jetty) and update to the latest core.async version. Resolves #695
- BREAKING CHANGE: Update Pedestal's OpenTracing-related protocol implementations by removing the extension of TraceSpan, TraceSpanLog, TraceSpanLogMap and TraceSpanBaggage to Scope. This aligns Pedestal's OpenTracing support with OpenTracing version 0.33. Affected implementations should be changed to interact with spans directly, as per the Pedestal Tracing sample, as opposed to going through the Scope instance. Resolves #693
- Adds a missing arity to TraceOrigin/-span for nils. #686
- Updates the SSLContextFactory used for configuring Jetty. This context factory supports more complicated SSL setups. #684
- Websocket handlers were added to handle flow control/backpressure asynchronously #497
- Fix override logger optionality when using io.pedestal.log/log #662
- Fix Critical Vulnerability in Eclipse Jetty 9.4.18.v20190429 (CVE-2020-27216) #672
- Fix print-method generates invalid edn when printing interceptors without name #678
- Fix incorrect arity 5 for io.pedestal.http.route.definition.table/syntax-error #683
- The
fast-resource
interceptor now passes on context correctly. Resolves #658 - Pedestal now supports overriding the Jetty thread pool. #655.
- Fix FileChannel/open usage in
fast-resource
. Resolves #651. - Clearer error messaging when the AWS XRay tracer is not registered. #617.
- Fix error suppression bug. See PR #645.
- Use openjdk Docker image in service template. Resolves #642.
- The test ServletHttpRequest now returns a StringBuffer on getRequestURL.
- Fix override-logger usage in
log
function. Resolves #638. - Fix setting initial tags in X-Ray segment/subsegment. Resolves #626.
- Add test support for HttpServletResponse SendError.
- Fix tracing examples and updates some samples.
- Fixes the
Template resource 'leiningen/new/pedestal_service/.gitignore' not found.
error encountered when runninglein pedestal-service [app-name]
with the Pedestal0.5.6
release.
- Resolves Pedestal dependencies have CVEs of high/critical severity #619
- It is now possible to override the service configuration's HttpConfiguration (jetty only) #615.
- The
url-for
:strict-path-params?
option is now more strict. Nil values are not allowed. Addresses #602. - Bumped dependencies (see PR #620 for details).
- Added a json-api sample.
- Pedestal.log now adheres to recent ns spec changes allowing its use with Clojure 1.10. Addresses issue #603.
- Fix for pedestal.log's distributed tracing support when passing a map to
log/log-span
. - Fix async termination. Addresses issue #581.
- Fix recursive loop error in API Gateway async utilities.
io.pedestal/pedestal.log
now provides a functional logging interfaceio.pedestal/pedestal.log
now ships with basic support for MDC- Dependencies have been bumped project wide
- javac-options source/target bumped to JDK 1.8
- Added support for pre-parsed query params
- More sample projects
- Distributed tracing support
- Pedestal AWS support
- AWS XRay
- AWS Lambda
- Dev-mode CSP setting is now correctly quoted.
- Jetty deps bumped up, fixing the JDK9 issue in the process (#555 #552).
- Tomcat deps bumped up, fixing an initialization bug that was lingering.
- SSE metric increment/decrement correctly accounted for in all branches #548.
- SSE safely runs the handling loop in a try/finally block, to ensure shutdown and cleanup always happens #560.
- BREAKING CHANGE: nil
::host
in service map defaults to localhost now (rather than being container specific) #557. - Content-negotiation response map now conforms to Ring spec #540.
response-for
now catches nil header values early, with a helpful exception #554.
For a full list of changes, please see this comparison of 0.5.3...0.5.4.
For more detailed release notes, refer to the 0.5.4 release document.
- CSRF default interceptor now implies
body-params
when turned on - The internal linker map within
url-for
is now delayed, while upholding the existing API not-found
andrequest-logging
default interceptors are now optional and can be toggled in the Service Map- All Routers are verb-neutral. Table Routes is the only verb-neutral data definition currently
- Service Template improves the developer experience around CSP (mostly turned off in dev-mode)
url-for
correctly handles trailing slashes- Clojure 1.9.0 and core.async spec bugs all addressed by bumping dependencies
- Servlet Chain Provider correctly handles multi-valued header entries
For a full list of changes, please see this comparison of 0.5.2...0.5.3.
- Immutant WebSocket support added
- Dependency refresh; Logback config updates based on latest version
- Sample and doc updates
- Secure Headers now supports Content Security Policy, Download Options, and Cross Domain Policy settings
response-for
now correctly handles Transit bodies (requests and replies)- CSRF double-submit cookie can now bootstrap itself even if sessions are turned off
- Metric name formatting was breaking StatsD and other aggregators; A new format function fixes this
For a full list of changes, please see this comparison of 0.5.1...0.5.2.
- New module/artifact layout. Internal pieces (interceptor chain, routing, logging/metrics) can be individually consumed
- WebSocket interface improvements to support new initializations/setups
- Configurable SSL options for Jetty
- The ability to completely disable HTTP on Jetty if you want to force HTTPS only
- HTTP/2 and ALPN support through a Java Agent
- New Pedestal sit and documentation updates
For a full list of changes, please see this comparison of 0.5.0...0.5.1.
- Map-tree router (used by default)
- Servlet independence via Chain Providers between the container and the Interceptor Chain
- Jetty has ALPN, HTTP/2, and WebSocket support
- Interceptor chain refactor
- Interceptor chain can be run in, out, or in-out; Can now handle streams of data
- Metrics tooling and API added. Reports/publishes to JMX by default
- Service template has Docker and OSv support -- Dockerfile and Capstanfile
- Service template has ALPN boot-dep configured. Comment out or remove if not using ALPN (HTTP/2)
- Route definition API refactored
- Table-routes format added
- Terse-route parsing and error reporting improved
- Request API added while creating Chain Providers; Zero-copy, Lazy, and Map requests added
- Support for SSE Event-Id added
- Support for Content-Negotiation added
- Support for SSL added to embedded Tomcat
- WAR tooling added to service-tools
For a full list of changes, please see this comparison of 0.4.1...0.5.0.
- Bug fixes for tree-based router - you can no longer fall off the tree
- NIO speed enhancements - utilize a better API call
response-for
split apart to allow for better instrumentation and test controlresponse-for
now handles async use- Dependencies updated
- SSE buffer bug patched - can't resuse core.async buffers
- SSE updated for open-ended option; New option for cleanup callback added
- Samples and docs cleaned up and improved
- Dedicated branches for HTTP2/ALPN support and WebSockets (not integrated into the interceptor chain)
For a full list of changes, please see this comparison of 0.4.0...0.4.1.
- Tree-based router (used by default)
- Open routing (users can set their own router)
- Robust error-handler interceptor (pattern-matching across all interceptors)
- Updated Interceptor API (built around a protocol / open for extension)
- Updated documentation samples
- Bug fixes and small enhancements to the testing tools
For a full list of changes, please see this comparison of 0.3.1...0.4.0.
- Container specific functionality is tucked behind a protocol
- Immutant added as a supported platform type
- NIO support added for Jetty and Immutant
- SSE now passes along the original context to the
start-fn
- Map-based terse route format added
- Servlet integration uses Clojure Java API instead of RT
- Transit support added for requests and responses
For a full list of changes, please see this comparison of 0.3.0...0.3.1.
- Performance optimizations and new connection code
- core.async channel-based SSE
- Better/cleaner SSE heartbeat threadpool
- Jetty9, Tomcat8, Clojure 1.6, Servlet 3.1
- Open HTTP verb smuggling
- CSRF-protection interceptor in the default interceptors (you need to set options for it to turn on)
- Sessions are http-only by default (pushed up to Ring)
- Secure-headers interceptor in the default interceptors
- Servlet filters can be dropped directly into a service-map definition
- Namespace refactor
- Simpler template and less dev-tool trickery
- New public API exposed for building, composing, starting, and stopping services
- Dependencies upgraded
- Bug fixes
Details will emerge in an upcoming blog post and within the guides and docs here.
For a full list of changes, please see this comparison of 0.2.2...0.3.0.
Bug fix release preceding some exciting (and breaking) 0.3.0 changes. Unless any major bugs are discovered, no further work will continue on the 0.2.x stream.
For a full list of changes, please see this comparison of 0.2.1...0.2.2.
Small bug fix for app-template.
For a full list of changes, please see this comparison of 0.2.0...0.2.1.
This is a big one folks. Developer tooling has moved from generated projects into the app- and service-tools libraries.
If you want to take advantage of all the super-awesome new features then further action is required. See the respective changelogs in App and Service for more info.
-
Developer tooling has moved in its entirety to app-tools.
Notable improvements:
- Tooling functions are automatically included when running
lein repl
. - App configuration can be reloaded with
(reload-config)
- Future upgrades to tooling will be incorporated more easily.
Additionally, app configuration is specified by an EDN file (instead of an executable Clojure file.) New projects will make use of this feature, but pre-0.2.0 generated projects will not.
You do not have to make this upgrade, but we suggest you do.
The easiest way to upgrade is to re-generate your application with the 0.2.0 app-template and transfer your existing code into it. It is possible, however, to migrate your existing application.
How to migrate a 0.1.x project to 0.2.0: 1. Upgrade your project's pedestal-app dependencies to version
"0.2.0"
2. Remove thedev/
folder. 3.$ touch config/user.clj
-- This is needed for:repl-options
with:init user
to work. 4. Update yourproject.clj
's:main
and:repl-options
keys like so. 5. Add the piggieback dependency to yourproject.clj
([com.cemerick/piggieback "0.1.0"]
). 6. Update your application'sconfig.clj
file. There are two ways to do this... 1. *If you have not modified yourconfig.clj
: Generate a new application with the same name as your existing application, and steal theconfig.edn
file from it. 2. If you have changed yourconfig.clj
, or you're a glutten for punishment perform these steps (looking like this is our goal): 1.mv config/config.clj config/config.edn
2. Remove thens
declaration. 3. Unwrap theconfigs
def into a raw map. 4. Remove quotes from quoted namespaces. Look in :main and :renderer keys. 5. At path[:build :watch-files]
,(compile/html-files-in "app/templates")
should become a map of tags to regex pattern strings like{:html ["^app/templates"]}
. Note these are string regex patterns, not regexps--regexps aren't supported by EDN. 6. At path[:build :triggers]
, existing strings should be converted to string regex patterns. For example, the original{:html ["project-name/rendering.js"]}
would become{:html ["project-name//rendering\\.js$"]}
. - Tooling functions are automatically included when running
-
Tooling's
cljs-repl
is now provided by Chas Emerick's Piggieback. -
Tooling's
cljs-repl
is now more clear about usage. This fixes #93, #90. -
App's ClojureScript dependency has been bumped to r1835. Namespaced keywords are now allowed (
::msg/topic
)! -
Logging in the browser is now grouped. #95
-
The template now includes a
:ui
aspect for rendering thesimulated
behavior. #184, #187 -
Added the
:read-as
option formsg/param
. Setting to:data
causes collected values to be parsed by the Clojure reader. #166*
-
Service tooling has moved out of generated projects into a service-tools library.
Notable improvements:
- Tooling functions are automatically included when running
lein repl
. - Future upgrades to tooling will be incorporated more easily.
There is a bit of migration necessary to move existing projects to 0.2.0 tooling. You don't have to make this change, but we suggest you do.
How to migrate a 0.1.x project to 0.2.0: 1. Update your project's dependencies to match the new ones: 1. Upgrade your project's pedestal-service dependencies to version
"0.2.0"
. 2. Add[io.pedestal/pedestal.service-tools "0.2.0"]
as a dependency. 3. Remove logback and slf4j logging dependencies. 2. Remove thedev/
folder 3.$ touch config/user.clj
-- This is needed for:repl-options
with:init user
to work. 4. Update yourproject.clj
's:main
and:repl-options
keys to match the new template project.clj. 5. Pare down your src/**/server.clj file to match the new template server.clj. - Tooling functions are automatically included when running
-
Service now uses Cheshire instead of clojure.data.json for constructing
json-response
s and parsing json bodies. #162This change does eliminate some JSON parsing options that were previously possible in 0.1.10. Specifically the following options are no longer supported:
:eof-error?
- "If true (default) will throw exception if the stream is empty.":eof-value
- "Object to return if the stream is empty and eof-error? is false. Default is nil."
If your application makes use of these options you will need to construct a
body-params
interceptor with aparser-map
where you have swapped in your own#"^application/json"
key with acustom-json-parser
similar to the old version.That might look something like this:
;; In a utility namespace (require '[io.pedestal.service.http.body-params :as bp]) (defn old-style-json-parser ...) (def my-body-params (bp/body-params (-> (bp/default-parser-map) (assoc #"^application/json" (old-style-json-parser)))))
-
The default behavior of the
body-params
interceptor now keywordizes JSON keys. To retain the old behavior, create abody-params
interceptor like so:(require '[io.pedestal.service.http.body-params :as bp]) (def string-keys-body-params (bp/body-params (bp/default-parser-map :json-options {:key-fn nil})))
-
A bug with CORS headers has been fixed.
-
The default MIME type has been returned to text/plain (it was a bug that it changed to octet-stream.)
For a full list of changes, please see this comparison of 0.1.10...0.2.0.
- The messages queue is now a priority queue. Specify
msg/priority :high
in a message for that message to be processed before all other unadorned messages. 2495b9a5 - Various improvements that make it easier to run in a web worker (more on that to follow, 😉)
io.pedestal.service.http.route/url-for
now accepts a:fragment
option for specifying URL fragments (i.e `http://example.com/#foobars). #85io.pedestal.service.http.body-params
's edn and json parsers can now be configured (both alone and as part ofdefault-parser-map
). #96, #97, #98
For a full list of changes, please see this comparison of 0.1.9...0.1.10.
- All Pedestal libraries now properly depend on Clojure 1.5.1.
- The dataflow engine now properly reports changes when nodes have nil or falsey values. #78
- Messages that throw exceptions during processing now log an error message.
- Templates can now insert content at a specific index with
io.pedestal.app.render.push.templates/insert-t
. #81 - Generated
dev/dev.clj
now uses(start)
instead of(run)
, bringing it in line with pedestal-service. #84
For a full list of changes, please see this comparison of 0.1.8...0.1.9.
-
App and service templates now allow creating projects with namespaces #68.
$ lein new pedestal-app com.example/foo ... creates foo/ with src/com/example/foo/*.clj
- Corrected a test error in the generated service template project.
For a full list of changes, please see this comparison of 0.1.7...0.1.8.
- The new simplified dataflow engine is here! We're working to update our documentation and samples now. Stay informed by following @pedestal_team on twitter.
- Existing applications will continue to function normally.
io.pedestal.app.templates/dtfn
now allows for more than one data field #60.
- Empty EDN responses are now handled gracefully #69.
- Resources for services can now be drawn from
resources/
#51. - Typo fixes in HTML and JSON interceptors #72.
- Corrected a few places the
Content-Type
header was not being set properly #58, #65.
For a full list of changes, please see this comparison of 0.1.6...0.1.7.
-
Context paths now work with JBoss
-
It is now possible to specify TCP port in routes (default: 8080). Specified ports will also be reflected in generated URL.
(defroutes routes [[:app1 8080 ["/" {:get app1-root}]] [:app2 8181 ["/" {:get app2-root}]]]
For a full list of changes, please see a comparison of 0.1.5...0.1.6.
We encountered a bug deploying version 0.1.4 so that release was re-done as version 0.1.5
lein clean
now correctly deletesout
directory.
- Added
text-as-html
anddata-as-json
interceptors. - Newly generated service apps assume content is
text/html
if not specified otherwise.
Special thanks to @ddeaguiar for grammar and spelling corrections, as well as his help in removing lein-marginalia as a dependency. We've updated the documentation with instructions on how to continue to generate marginalia documentation.
For a full list of changes, please see a comparison of 0.1.3...0.1.5.
- app-tools now serves every request with header Cache-Control: no-cache (#44) - @rkneufeld
- Add CORS support to SSE and service template - @timewald
For a full list of changes, please see a comparison of 0.1.2...0.1.3.
- Travis CI integration has been enabled (#27) - @cldwalker
- lein repl history is now ignored by git (#38) - @crimeminister
- app tests no longer have non-deterministic timing problems (#39) - @brentonashworth
- app-tools now plays (more) nicely with Windows (#23, #29, #31) - @djpowell, @rkneufeld
- Add support for Heroku (#18) - @aredington, @cldwalker, @hiredman, @timewald
- An HTTP status is now sufficient to bypass the not-found interceptor (whereas it used to require headers) (#30, #34) - @hiredman, @rkneufeld
- Removed a number of incorrect :or keys (#32) - @cldwalker
- Usage of 'read-string' has been audited and corrected (#40) - @stuartsierra
- io.pedestal.service.http.body-params/set-content-type now uses correct casing for HTTP headers (#35) - @stuarth