Skip to content

Migration Guide to 2.0.0

Tommi Reiman edited this page Jul 31, 2017 · 16 revisions

NOTE: Compojure-api 2.0.0 has not been released yet. For a preview, you can try the Compojure-api 1.2.0 alphas. What was supposed to become Compojure-api 1.2.0 will be released as 2.0.0.

About

Compojure-api 2.0.0 has the following breaking changes:

  • Compojure-api 2.0.0 requires Java 1.8 or later (because of Muuntaja).
  • We now use Muuntaja instead of ring-middleware-format; :format options need migrating
  • Static context calls are optimized in a way that can break some existing code.
  • Request and response coercion now depends on the content type.
  • swagger-ui and swagger-docs now take options map instead of varargs.
  • middleware was removed; use route-middleware instead

The details are below.

NOTE: If you're using version older than 1.1.x, please first upgrade to 1.1.10 (the last pre-2.0.0 version) before upgrading to 2.0.0. If you're using pre-1.0.0 version, see the migration guide to 1.0.0.

Muuntaja

We now use Muuntaja instead of ring-middleware-format for format negotiation, encoding, and decoding. In benchmarks, Muuntaja is much faster than ring-middleware-format.

  • The api option :format has been removed. Use :formats instead. It should be either a Muuntaja instance, Muuntaja options map, or nil to disable Muuntaja.
  • See the instructions for configuring Muuntaja.
    • If you haven't configured :format, you can ignore this.
  • By default, support for application/yaml & application/msgpack have been dropped (smaller core). If you want to use them, do this:
    • add a dependency to [circleci/clj-yaml "0.5.6"] &/ [clojure-msgpack "1.2.0"]
    • configure your api to serve those formats (coercion is pre-set for both):
(require '[muuntaja.core :as muuntaja])
(require '[muuntaja.format.yaml :as yaml-format])
(require '[muuntaja.format.msgpack :as msgpack-format])

(api
  {:formats (-> muuntaja/default-options)
                (yaml-format/with-yaml-format)
                (msgpack-format/with-msgpack-format))}
  ...)

Static context optimization

If your context is static (there are no route parameters), it's evaluated only once. This makes it faster, but code like this won't work as expected:

(context "/static" []
  (if (its-noon?)
    (GET "/noon-route" [] (ok "it's noon")))

In this case, replace context with dynamic-context. If you're unsure, you can replace any context calls with dynamic-context. This gives you the same behavior and performance as context in Compojure-api 1.1.

Request and response coercion

Request and response coercion now depends on the format negotiated by Muuntaja. The old default was to coerce all requests and responses with json-coercion-matcher. The new defaults are as follows:

Format Request Response
application/edn validate validate
application/transit+json validate validate
application/transit+msgpack validate validate
application/json json-coercion-matcher validate
application/msgpack json-coercion-matcher validate
application/x-yaml json-coercion-matcher validate

How does this effect my routes?

Before, this was ok:

(api
  (GET "/tags" []
    :return {:tags #{s/Keyword}}
    (ok {:tags #{"kikka", "kakka", kukka"}})))

With 2.0.0, it will fail as the return value is not coerced, just validated by default. One can set back the JSON-coercion either as default for all formats or for certain formats only:

(require '[compojure.api.coercion.schema :as cs])

;; for all formats
(def json-coerce-all-responses
  (cs/create-coercion
    (assoc-in cs/default-options [:response :default] cs/json-coercion-matcher)))

;; just for application/json
(def json-coerce-responses
  (cs/create-coercion
    (assoc-in cs/default-options [:response :formats "application/json"] cs/json-coercion-matcher)))

(api
  {:coercion json-coerce-all-responses}
  (GET "/tags" []
    :return {:tags #{s/Keyword}}
    (ok {:tags #{"kikka", "kakka", kukka"}})))
  • If you have custom coercions, they should continue to work as before.
  • default-coercion-matchers has been replaced by default-coercion-options.

swagger-ui and swagger-docs

swagger-ui and swagger-docs now take an options map with a path key instead of an optional path and vararg options.

;; Compojure-api 1.1
(swagger-ui "/swagger")

;; Compojure-api 2.0
(swagger-ui {:path "/swagger"})

swagger-routes and :swagger api options work as before.

middleware and route-middleware

middleware has been removed, because it dangerously applied the middleware even to requests that didn't match the contained routes. Replace it with compojure.api.core/route-middleware, which only applies middlewares when the request is matched against the contained routes.

Changes to not-that-public APIs

You probably aren't using these, but if you are, here you go:

  • compojure.api.routes/create was removed; use compojure.api.routes/map->Route instead.

Still having problems?

If you need help, find us on #ring-swagger in Clojurians Slack (join) or open an issue. If this guide is missing something relevant, feel free to update it. All feedback welcome.

Clone this wiki locally