See also: compojure-api 1.1.x changelog
:{body,query,headers}, in particular if anything other than 2 elements was provided
-Dcompojure.api.meta.allow-bad-{body,query,headers}=true:{return,body,query,responses,headers,coercion,{body,form,header,query,path}-params} schemas/arguments are evaluated/expanded
:{form,multipart}-params :info :public :parameters :formData field at runtime:outer-lets field to restructure-param result which wraps entire resulting formstatic-context macro and replace with equivalent expansion without relying on compojure internals.defapi (and deprecate it)compojure.api.routes/createmiddleware (and deprecate it)context :dynamic by default:static true option to context-Dcompojure.api.meta.static-context-coach=print to print hints-Dcompojure.api.meta.static-context-coach=assert to assert hints:json & :string coercion type transformers[metosin/spec-tools "0.9.1"] is available but we use "0.9.0"
[metosin/muuntaja "0.6.4"] is available but we use "0.6.3"
[metosin/ring-swagger "0.26.2"] is available but we use "0.26.1"
Spec Coercion enchancements
st/coerce and st/conform, by Miguel PingUpdated dependencies:
[prismatic/schema "1.1.10"] is available but we use "1.1.9"
[metosin/muuntaja "0.6.3"] is available but we use "0.6.1"
[com.fasterxml.jackson.datatype/jackson-datatype-joda "2.9.8"] is available but we use "2.9.7"
[metosin/spec-tools "0.9.0"] is available but we use "0.8.2"
clojure.spec problems for exception handlers, to use pretty-printers like expound:(require '[compojure.api.sweet :refer :all])
(require '[ring.util.http-response :refer :all])
(require '[compojure.api.exception :as ex])
(require '[expound.alpha :as expound])
(def printer
(expound/custom-printer
{:theme :figwheel-theme, :print-specs? false}))
(def app
(api
{:coercion :spec
:exceptions
{:handlers
{::ex/request-validation
(fn [e data request]
(printer (:problems data))
(ex/request-validation-handler e data request))
::ex/response-validation
(fn [e data request]
(printer (:problems data))
(ex/response-validation-handler e data request))}}}
(GET "/math" []
:query-params [x :- int?, y :- int?]
:return {:total pos-int?}
(ok {:total (+ x y)}))))
[ring/ring-core "1.7.1"] is available but we use "1.7.0"
[metosin/spec-tools "0.8.2"] is available but we use "0.8.0"
[metosin/ring-http-response "0.9.1"] is available but we use "0.9.0"
BREAKING: dropped support for Clojure 1.8.0
Latest features from spec-tools
spec-tools.core/spec, s/and, s/or, s/coll-of, s/keys, s/map-of, s/nillable and s/every) can be transformed without needing spec to be wrapped. Fallbacks to old conformed based approach.new deps:
[metosin/spec-tools "0.8.0"]
[com.fasterxml.jackson.datatype/jackson-datatype-joda "2.9.7"] is available but we use "2.9.6"
[ring/ring-core "1.7.0"] is available but we use "1.6.3"
[metosin/jsonista "0.2.2"] is available but we use "0.2.1"
[metosin/muuntaja "0.6.0"] is available but we use "0.6.0-alpha4"
[metosin/muuntaja "0.6.0-alpha4"] is available but we use "0.6.0-alpha3"
BREAKING: Don't encode response :body if Content-Type header is set.
update deps:
[metosin/muuntaja "0.6.0-alpha3"] is available but we use "0.6.0-alpha1"
java.security.SecureRandom can be serialized, via reflectionmuuntaja.core/install helper to add new formats:(require '[compojure.api.sweet :refer :all])
(require '[ring.util.http-response :refer :all])
(require '[muuntaja.core :as m])
(require '[muuntaja.format.msgpack]) ;; [metosin/muuntaja-msgpack]
(require '[muuntaja.format.yaml]) ;; [metosin/muuntaja-yaml]
(def formats
(m/create
(-> m/default-options
(m/install muuntaja.format.msgpack/format)
(m/install muuntaja.format.yaml/format)
;; return byte[] for NIO servers
(assoc :return :bytes))))
(api
{:formats formats}
(POST "/ping" []
(ok {:ping "pong"})))
compojure.api.middleware/wrap-format to support multiple apis (or api + external static routes)in a project, fixes #374(require '[compojure.api.sweet :refer :all])
(require '[ring.util.http-response :refer [ok]])
(require '[compojurea.api.middeware :as middleware])
(-> (routes
(api
(POST "/echo1" []
:body [body s/Any]
(ok body)))
(api
(POST "/echo2" []
:body [body s/Any]
(ok body))))
(middleware/wrap-format))
[ikitommi/linked "1.3.1-alpha1"] ;; waiting for original to update
[metosin/ring-swagger "0.26.1"] is available but we use "0.26.0"
[metosin/muuntaja "0.6.0-alpha1"] is available but we use "0.5.0"
[com.fasterxml.jackson.datatype/jackson-datatype-joda "2.9.6"] is available but we use 2.9.5"
welcome spec transformers!! might break custom coercion implementations
update deps:
[potemkin "0.4.5"] is available but we use "0.4.4"
[prismatic/schema "1.1.9"] is available but we use "1.1.7"
[frankiesardo/linked "1.3.0"] is available but we use "1.2.9"
[compojure "1.6.1"] is available but we use "1.6.0"
[metosin/spec-tools "0.7.0"] is available but we use "0.6.1"
[metosin/jsonista "0.2.0"] is available but we use "0.1.1"
[metosin/ring-swagger "0.26.0"] is available but we use "0.25.0"
[metosin/spec-tools "0.6.1"] is available but we use "0.5.1"
Maintenance 1.1 release, adding several patches from 2.0 branch.
[metosin/muuntaja "0.5.0"] is available but we use "0.4.1"
defapi. def + api should be used instead.[metosin/muuntaja "0.4.2"] is available but we use "0.4.1"
[metosin/ring-swagger "0.25.0"] is available but we use "0.24.3"
config not found. There is an issue in ring-swagger.[metosin/ring-swagger-ui "2.2.10"] is available but we use "3.0.17"
[metosin/muuntaja "0.4.1"] is available but we use "0.4.0"
Fixes Muuntaja-bug of randomly failing on :body parameters with some server setups.
updated deps:
[prismatic/plumbing "0.5.5"] is available but we use "0.5.4"
[metosin/muuntaja "0.4.0"] is available but we use "0.3.3"
[ring/ring-core "1.6.3"] is available but we use "1.6.2"
[metosin/spec-tools "0.5.1"] is available but we use "0.5.0"
Better error messages for bad letk syntax by Erik Assum, fixes #354
:coercion applies for context parameters too (not just childs)
updated deps:
[metosin/muuntaja "0.3.3"] is available but we use "0.3.2"
dynamic-context is removed in favor of :dynamic true meta-data for contexts:(require '[compojure.api.help :as help])
(help/help :meta :dynamic)
; :dynamic
;
; If set to to `true`, makes a `context` dynamic,
; e.g. body is evaluated on each request. NOTE:
; Vanilla Compojure has this enabled by default
; while compojure-api default to `false`, being
; much faster. For details, see:
;
; https://github.com/weavejester/compojure/issues/148
;
; (context "/static" []
; (if (= 0 (random-int 2))
; ;; mounting decided once
; (GET "/ping" [] (ok "pong")))
;
; (context "/dynamic" []
; :dynamic true
; (if (= 0 (random-int 2))
; ;; mounted for 50% of requests
; (GET "/ping" [] (ok "pong")))
routes and context:(context "/api" []
(for [path ["/ping" "/pong"]]
(GET path [] (ok {:path path}))))
[metosin/ring-swagger "0.24.3"] is available but we use "0.24.2"
ANY produces swagger-docs for all methods, thanks to Anthony
Updated deps:
[metosin/spec-tools "0.5.0"] is available but we use "0.4.0"
:pred under Spec :problems, fixes #345:spec coercion is tried without required dependenciesAligned with the latest spec-tools: [metosin/spec-tools "0.4.0"]
To use Clojure 1.9 & Spec with Swagger, these need to be imported:
[org.clojure/clojure "1.9.0-beta2"]
[metosin/spec-tools "0.4.0"]
ring.middleware.http-response exception handling directly:(require '[compojure.api.sweet :refer :all])
(require '[ring.util.http-response :as http])
(api
{:exceptions {:handlers {::http/response handle-thrown-http-exceptions-here}}
(GET "/throws" []
(http/bad-request! {:message "thrown response"})))
api instance (if not undefined, e.g. nil) is injected into :compojure.api.request/muuntaja for endpoints to use.
path-for and path-for* now use this to encode path-parameters.(require '[compojure.api.sweet :refer :all])
(require '[compojure.api.request :as request])
(require '[muuntaja.core :as m])
(api
(GET "/ping" {:keys [::request/muuntaja]}
(ok {:json-string (slurp (m/encode muuntaja "application/json" [:this "is" 'JSON]))})))
Muuntaja-instance optins are merged correctly.(require '[compojure.api.sweet :refer :all])
(require '[ring.util.http-response :refer [ok]])
(require '[metosin.transit.dates :as transit-dates])
(require '[muuntaja.core :as m])
(def muuntaja
(m/create
(-> muuntaja/default-options
(update-in
[:formats "application/transit+json"]
merge
{:decoder-opts {:handlers transit-dates/readers}
:encoder-opts {:handlers transit-dates/writers}}))))
(api
{:formats muuntaja}
(GET "/pizza" []
(ok {:now (org.joda.time.DateTime/now)})))
[cheshire "5.7.1"]
[org.tobereplaced/lettercase "1.0.0"]
[potemkin "0.4.4"] is available but we use "0.4.3"
[metosin/ring-swagger "0.24.2"] is available but we use "0.24.1"
[metosin/spec-tools "0.4.0"] is available but we use "0.3.2"
application/yaml & application/msgpack. If you want to add them back, you need to manually add the dependencies below and configure Muuntaja to handle those:(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))}
...)
[circleci/clj-yaml "0.5.6"]
[clojure-msgpack "1.2.0"]
spec coericon also calls s/unform after s/conform, e.g. specs like (s/or :int spec/int? :keyword spec/keyword?) work now too.
updated dependencies:
[circleci/clj-yaml "0.5.6"] is available but we use "0.5.5"
[metosin/muuntaja "0.3.2"] is available but we use "0.3.1"
[ring/ring-core "1.6.2"] is available but we use "1.6.1"
[metosin/ring-swagger "0.24.1"] is available but we use "0.24.0"
updated deps for the 1.*
BREAKING: in compojure.api.swagger, the swagger-ui and swagger-docs now take options map with path key instead of separate optional path & vararg opts.
swagger-routes and thus be unaffected of this.updated dependencies:
[prismatic/plumbing "0.5.4"] is available but we use "0.5.3"
[compojure "1.6.0"] is available but we use "1.5.2"
[prismatic/schema "1.1.6"] is available but we use "1.1.3"
[ring-middleware-format "0.7.2"] is available but we use "0.7.0"
[metosin/ring-http-response "0.9.0"] is available but we use "0.8.1"
[metosin/ring-swagger "0.24.1"] is available but we use "0.22.14"
Spec coercion endpoints produce now Swagger2 data
To use Clojure 1.9 & Spec with Swagger, these need to be imported:
[org.clojure/clojure "1.9.0-alpha17"]
[metosin/spec-tools "0.3.0"]
[org.clojure/clojure "1.8.0"]
[metosin/spec-tools "0.3.0" :exclusions [org.clojure/spec.alpha]]
[clojure-future-spec "1.9.0-alpha17"]
INFO :spec swagger generation enabled in compojure.api
[metosin/spec-tools "0.3.0"] is available but we use "0.2.2"
pr-str value.resource body-params are associated over existing instead of merged. e.g. extra params are really stripped off.Update to latest Muuntaja.
updated deps:
[metosin/muuntaja "0.3.1"] is available but we use "0.2.2"
compojure.api.request back to src.:compojure.api.request/coercioncompojure.api.coercion, replacing compojure.api.coerce.:coercion can be set to api, context, endpoint macros or a resource. It can be either:
compojure.api.coercion.core/CoercionCoercion via compojure.api.coercion.core/named-coercion multimethod.coercion is stored in Route :infoCoercion:(defprotocol Coercion
(get-name [this])
(get-apidocs [this spec data])
(encode-error [this error])
(coerce-request [this model value type format request])
(coerce-response [this model value type format request]))
:schema (default) resolves to compojure.api.coercion.schema/SchemaCoercion:spec resolves to compojure.api.coercion.spec/SpecCoercion
nil removes the coercion (was: nil or (constantly nil)).(require '[compojure.api.sweet :refer :all])
(require '[clojure.spec.alpha :as s])
(require '[spec-tools.spec :as spec])
(s/def ::id spec/int?)
(s/def ::name spec/string?)
(s/def ::description spec/string?)
(s/def ::type spec/keyword?)
(s/def ::new-pizza (s/keys :req-un [::name ::type] :opt-un [::description]))
(s/def ::pizza (s/keys :req-un [::id ::name ::type] :opt-un [::description]))
(resource
{:coercion :spec
:summary "a spec resource, no swagger yet"
:post {:parameters {:body-params ::new-pizza}
:responses {200 {:schema ::pizza}}
:handler (fn [{new-pizza :body-params}]
(ok (assoc new-pizza :id 1)))}})
(require '[spec-tools.data-spec :as ds])
(s/def ::id spec/int?)
(context "/spec" []
:coercion :spec
(POST "/pizza" []
:summary "a spec endpoint"
:return ::pizza
:body [new-pizza ::new-pizza]
(ok (assoc new-pizza :id 1)))
(POST "/math/:x" []
:summary "a spec endpoint"
:return {:total int?}
:path-params [x :- spec/int?]
:query-params [y :- spec/int?,
{z :- spec/int? 0}]
(ok {:total (+ x y z)})))
[org.clojure/clojure "1.9.0-alpha17"]
[metosin/spec-tools "0.2.2"]
[org.clojure/clojure "1.8.0"]
[metosin/spec-tools "0.2.2" :exclusions [org.clojure/spec.alpha]]
[clojure-future-spec "1.9.0-alpha17"]
BREAKING: Clojure 1.7.0 is no longer supported (no back-port for clojure.spec).
use ClassLoader -scoped Schema memoization instead of api-scoped - same for anonymous map specs
:body-params is available for exception handlers, fixes #306 & #313
BREAKING: Restructuring internal key changes in compojure.api.meta:
:swagger is removed in favor of :info.[:info :public] instead of [:swagger]:info can contain:
:static-context? -> true if the context is internally optimized as static:name, route name:coercion, the defined coercion(let [app (GET "/" []
:return {:x String}
(ok {:kikka 2}))]
(try
(app {:request-method :get, :uri "/"})
(catch Exception e
(ex-data e))))
; {:type :compojure.api.exception/response-validation,
; :validation :schema,
; :in [:response :body],
; :schema {:x java.lang.String},
; :errors {:x missing-required-key,
; :kikka disallowed-key},
; :response {:status 200,
; :headers {},
; :body {:kikka 2}}}
(let [app (GET "/" []
:query-params [x :- String]
(ok))]
(try
(app {:request-method :get, :uri "/" :query-params {:x 1}})
(catch Exception e
(ex-data e))))
; {:type :compojure.api.exception/request-validation,
; :validation :schema,
; :value {:x 1},
; :in [:request :query-params],
; :schema {Keyword Any, :x java.lang.String},
; :errors {:x (not (instance? java.lang.String 1))},
; :request {:request-method :get,
; :uri "/",
; :query-params {:x 1},
; :route-params {},
; :params {},
; :compojure/route [:get "/"]}}
Introduce dynamic-context that works like context before the fast context optimization (#253).
context, they will not work as intended. If you need this, replace context with dynamic-context.For example:
;; compojure-api 1.1
(context "/static" []
(if (its-noon?)
(GET "/noon-route" [] (ok "it's noon")))
;; compojure-api 1.2:
(dynamic-context "/static" []
(if (its-noon?)
(GET "/noon-route" [] (ok "it's noon")))
1.0.0 (for :parameters and :middlewares)BREAKING: resource function is always 1-arity, options and info are merged.
resource can have :middleware on both top-level & method-level.
(def mw [handler value]
(fn [request]
(println value)
(handler request)))
(resource
{:middleware [[mw :top1] [mw :top2]]
:get {:middleware [[mw :get1] [mw :get2]]}
:post {:middleware [[mw :post1] [mw :post2]]}
:handler (constantly (ok))})
[prismatic/schema "1.1.6"] is available but we use "1.1.5"
resource separates 1-arity :handler and 3-arity :async-handler. Rules:
:handler is used, sent via compojure.response/render:async-handler is used, with fallback to :handler.
compojure.response/send so manifold Deferred and core.async ManyToManyChannel can be returned.(require '[compojure.api.sweet :refer :all])
(require '[clojure.core.async :as a])
(require '[manifold.deferred :as d])
(resource
{:summary "async resource"
:get {:summary "normal ring async"
:async-handler (fn [request respond raise]
(future
(Thread/sleep 100)
(respond (ok {:hello "world"})))
nil)}
:put {:summary "core.async"
:handler (fn [request]
(a/go
(a/<! (a/timeout 100))
(ok {:hello "world"})))}
:post {:summary "manifold"
:handler (fn [request]
(d/future
(Thread/sleep 100)
(ok {:hello "world"})))}})
[ring/ring-core "1.6.1"] is available but we use "1.6.0"
[ring/ring-core "1.6.0"]compojure.api.core depends on compojure.api.async
Deferred and core.async ManyToManyChannel can be returned from endpoints.resource now supports async (3-arity) handlers as well.(resource
{:parameters {:query-params {:x Long}}
:handler (fn [request respond raise]
(future
(res (ok {:total (-> request :query-params :x)})))
nil)})
[ring/ring-core "1.6.0"]
[cheshire "5.7.1"] is available but we use "5.7.0"
[compojure "1.6.0"] is available but we use "1.5.2"
[prismatic/schema "1.1.5"] is available but we use "1.1.4"
[prismatic/plumbing "0.5.4"] is available but we use "0.5.3"
[metosin/ring-http-response "0.9.0"] is available but we use "0.8.2"
[metosin/ring-swagger "0.24.0"] is available but we use "0.23.0"
[compojure "1.6.0"] is available but we use "1.6.0-beta3"
[org.clojure/clojure "1.9.0-alpha15"] (requires Midje 1.9.0-alpha6)[metosin/muuntaja "0.2.1"] is available but we use "0.2.0-20170323.064148-15"
Initial support for Async Ring, using CPS, manifold or core.async
compojure.api.core/ring-handler to turn a compojure-api route into a 1-arity function
Fn:params are populated correctly from :body-params
Allow nil paths in routing, allows easy (static) conditional routing like:
(defn app [dev-mode?]
(api
(GET "ping" [] (ok "pong"))
(if dev-mode?
(GET "/drop-the-db" [] (ok "dropped")))))
java.io.File as response type, mapping to file downloads
(GET "/file" []
:summary "a file download"
:return java.io.File
:produces #{"image/png"}
(-> (io/resource "screenshot.png")
(io/input-stream)
(ok)
(header "Content-Type" "image/png"))))
Fix help-for for some restructure methods #275 by Nicolás Berger
BREAKING: in compojure.api.swagger, the swagger-ui and swagger-docs now take options map with path key instead of separate optional path & vararg opts.
swagger-routes and thus be unaffected of this.BREAKING: middleware is removed because it dangerously applied the
middleware even to requests that didn't match the contained routes. New route-middleware
only applies middlewares when the request is matched against contained routes.
route-middleware is not exposed in sweet namespace but is available at compojure.api.coreUpdated deps:
[metosin/muuntaja "0.2.0-20170323.064148-15"] is available but we use "0.2.0-20170122.164054-8"
[prismatic/schema "1.1.4"] is available but we use "1.1.3"
[metosin/ring-swagger-ui "2.2.10"] is available but we use "2.2.8"
[metosin/ring-swagger "0.23.0"] is available but we use "0.22.14"
[metosin/ring-http-response "0.8.2"] is available but we use "0.8.1"
[:exceptions :handlers] options also allows exception classes as keys.
:type-lookup, then by Exception class and it's superclasses.(api
{:exceptions
{:handlers
{::ex/default handle-defaults
java.sql.SQLException handle-all-sql-exceptions}}}
...)
compojure.api.help/help.(require '[compojure.api.help :refer [help]])
(help)
; ------------------------------------------------------------
; Usage:
;
; (help)
; (help topic)
; (help topic subject)
;
; Topics:
;
; :meta
;
; Topics & subjects:
;
; :meta :body
; :meta :body-params
; :meta :coercion
; :meta :components
; :meta :consumes
; :meta :description
; :meta :form-params
; :meta :header-params
; :meta :middleware
; :meta :multipart-params
; :meta :name
; :meta :no-doc
; :meta :operationId
; :meta :path-params
; :meta :produces
; :meta :responses
; :meta :return
; :meta :summary
; :meta :swagger
; :meta :tags
(help/help :meta :middleware)
; ------------------------------------------------------------
;
; :middleware
;
; Applies the given vector of middleware to the route.
; Middleware is presented as data in a Duct-style form:
;
; 1) ring mw-function (handler->request->response)
;
; 2) mw-function and it's arguments separately - mw is
; created by applying function with handler and args
;
; (defn require-role [handler role]
; (fn [request]
; (if (has-role? request role)
; (handler request)
; (unauthorized))))
;
; (def require-admin (partial require-role :admin))
;
; (GET "/admin" []
; :middleware [require-admin]
; (ok))
;
; (GET "/admin" []
; :middleware [[require-role :admin]]
; (ok))
;
; (GET "/admin" []
; :middleware [#(require-admin % :admin)]
; (ok))
;
(defmethod help/help-for [:restructuring :query-params] [_ _]
(help/text
"Restructures query-params with plumbing letk notation.\n"
"Example: read x and optionally y (defaulting to 1)"
"from query parameters. Body of the endpoint sees the"
"coerced values.\n"
(help/code
"(GET \"/ping\""
" :query-params [x :- Long, {y :- Long 1}]"
" (ok (+ x y)))")))
[metosin/muuntaja "0.2.0-20170130.142747-9"] is available but we use "0.2.0-20170122.164054-8"
this is an alpha release, feedback welcome
:body does not keywordize all keys,
true).resource under context requires exact routing match, fixes #269compojure.api.routes/Routes, returned routes don't commit to swagger-docs - as they can be generated at runtimecompojure.api.middleware, the default-coercion-matchers is removed in favour of create-coercion & default-coercion-optionscoercion should work as before, as the contract has not changedjson-coercion-matcher| 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 |
defaults as code:
(def default-coercion-options
{:body {:default (constantly nil)
:formats {"application/json" json-coercion-matcher
"application/msgpack" json-coercion-matcher
"application/x-yaml" json-coercion-matcher}}
:string string-coercion-matcher
:response {:default (constantly nil)
:formats {}}})
to create a valid coercion (for api or to routes):
;; create (with defaults)
(mw/create-coercion)
(mw/create-coercion mw/default-coercion-options)
;; no response coercion
(mw/create-coercion (dissoc mw/default-coercion-options :response)
;; disable all coercion
nil
(mw/create-coercion nil)
(context "/api" []
(GET "/ping" [] (ok))
(POST "/echo" []
:body [data {:name s/Str}]
:return {:name s/Str}
(ok data))
(context "/resource" []
(resource
{:get {:handler (constantly (ok))}})))
; #Route {:path "/api",
; :childs [#Route {:path "/ping"
; :method :get}
; #Route {:path "/echo",
; :method :post,
; :info {:parameters {:body {:name Str}},
; :responses {200 {:schema {:name Str}
; :description ""}}}}
; #Route {:path "/resource"
; :childs [#Route{:childs [#Route{:path "/"
; :method :get}]}]}]}
[cheshire "5.7.0"] is available but we use "5.6.3"
[metosin/muuntaja "0.2.0-20170122.164054-8"] is available but we use "0.2.0-20161031.085120-3"
[metosin/ring-http-response "0.8.1"] is available but we use "0.8.0"
[metosin/ring-swagger "0.22.14"] is available but we use "0.22.12"
[metosin/ring-swagger-ui "2.2.8"] is available but we use "2.2.5-0"
:format has been deprecated (fails at api creation time), use :formats instead. It consumes either a
Muuntaja instance, Muuntaja options map or nil (unmounts it). See how to configure Muuntaja how to use.contexts, #253 - use static routes if a context doesn't do any lexical bindings
context routing.:middleware for api & api-middleware, run last just before the actual routes. Uses same syntax as with the routing macros.(api
{:middleware [no-cache [wrap-require-role :user]]}
...)
[metosin/muuntaja "0.2.0-SNAPSHOT"]
[metosin/ring-swagger "0.22.12"] is available but we use "0.22.11"
[ring-middleware-format "0.7.0"]
[compojure "1.5.2"] is available but we use "1.5.1"
[metosin/ring-http-response "0.8.1"] is available but we use "0.8.0"
[metosin/ring-swagger "0.22.14"] is available but we use "0.22.11"
[metosin/ring-swagger-ui "2.2.8"] is available but we use "2.2.5-0"
:header-params with resources, #254[frankiesardo/linked "1.2.9"] is available but we use "1.2.7"
[metosin/ring-swagger "0.22.11"] is available but we use "0.22.10"
[metosin/ring-swagger-ui "2.2.5-0"] is available but we use "2.2.2-0"
Lot's of new swagger-bindings from Ring-swagger:
schema.core.defrecordorg.joda.time.LocalTimes/Any in body generates empty object instead of nilBundled with latest swagger-ui 2.2.2-0
Updated deps:
[metosin/ring-swagger "0.22.10"] is available but we use "0.22.9"
[metosin/ring-swagger-ui "2.2.2-0"] is available but we use "2.2.1-0"
Bundled with the latest Swagger-ui (2.2.1-0)
Updated deps:
[metosin/ring-swagger-ui "2.2.1-0"] is available but we use "2.1.4-0"
:content-type of user-defined formats are pushed into Swagger :produces and :consumes, thanks to Waldemar.(def custom-json-format
(ring.middleware.format-response/make-encoder cheshire.core/generate-string "application/vnd.vendor.v1+json"))
(api
{:format {:formats [custom-json-format :json :edn]}}
...)
[:api :disable-api-middleware?] to disable the api-middleware completely. With this set, api only produces the (reverse) route-tree + set's swagger stuff and sets schema coercions for the api.
(api
{:api {:disable-api-middleware? true}
;; Still available
:swagger {:ui "/api-docs"
:spec "/swagger.json"
:data {:info {:title "api"}}}}
...)
:data in swagger-routes can be overridden even if run outside of api:(def app
(routes
(swagger-routes
{:ui "/api-docs"
:spec "/swagger.json"
:data {:info {:title "Kikka"}
:paths {"/ping" {:get {:summary "ping get"}}}}})
(GET "/ping" [] "pong"))))
:format option in api-middleware causes all format-middlewares not to mount:exceptions option in api-middleware causes the exception handling to be disabled:coercion translates to same as setting it to (constantly nil)(api
{:exceptions nil ;; disable exception handling
:format nil ;; disable ring-middleware-format
:coercion nil} ;; disable all schema-coercion
;; this will be really thrown
(GET "/throw" []
(throw (new RuntimeException))))
[prismatic/schema "1.1.3"] is available but we use "1.1.2"
[frankiesardo/linked "1.2.7"] is available but we use "1.2.6"
fix reflection warning with logging, thanks to Matt K.
Empty contexts (/) don't accumulate to the path, see https://github.com/weavejester/compojure/issues/125
NOTE: update of ring-http-response had a breaking change:
updated dependencies:
[compojure "1.5.1"] is available but we use "1.5.0"
[metosin/ring-http-response "0.8.0"] is available but we use "0.7.0"
[cheshire "5.6.3"] is available but we use "5.6.1"
[prismatic/schema "1.1.2"] is available but we use "1.1.1"
[metosin/ring-http-response "0.7.0"] is available but we use "0.6.5"
[metosin/ring-swagger "0.22.9"] is available but we use "0.22.8"
[reloaded.repl "0.2.2"] is available but we use "0.2.1"
[peridot "0.4.4"] is available but we use "0.4.3"
[reloaded.repl "0.2.2"] is available but we use "0.2.1"
Response headers are mapped correctly, fixes #232
updated dependencies:
[metosin/ring-swagger "0.22.8"] is available but we use "0.22.7"
:swagger.(let [runtime-data {:x-name :boolean
:operationId "echoBoolean"
:description "Ehcoes a boolean"
:parameters {:query {:q s/Bool}}}]
(api
(GET "/route" []
:swagger runtime-data
(ok {:it "works"}))))
:route-params into :path-params with resources
(resource
{:parameters {:path-params {:id s/Int}}
:responses {200 {:schema s/Int}}
:handler (fnk [[:path-params id]]
(ok (inc id)))})
[prismatic/schema "1.1.1"] is available but we use "1.1.0"
compojure.api.swgger/validate to compojure.api.validator/validate.resource doesn't define a handler for a given request-method or for top-level, nil is returned (instead of throwing exeption)context. Trying to return a compojure.api.routing/Route from an endpoint like ANY will throw descriptive (runtime-)exception.(context "/hello" []
(resource
{:description "hello-resource"
:responses {200 {:schema {:message s/Str}}}
:post {:summary "post-hello"
:parameters {:body-params {:name s/Str}}
:handler (fnk [[:body-params name]]
(ok {:message (format "hello, %s!" name)}))}
:get {:summary "get-hello"
:parameters {:query-params {:name s/Str}}
:handler (fnk [[:query-params name]]
(ok {:message (format "hello, %s!" name)}))}}))
{:ui nil, :spec nil}. Setting up just the spec or ui, doesn't automatically setup the other (like previously):middleware, fixes #228describe works with anonymous body-schemas (via ring-swagger 0.22.7), Fixes #168[metosin/compojure-api "1.1.0" :exclusions [[metosin/scjsv]]]
[metosin/ring-swagger "0.22.7"] is available but we use "0.22.6"
[prismatic/plumbing "0.5.3"] is available but we use "0.5.2"
[cheshire "5.6.1"] is available but we use "5.5.0"
compojure.api.meta to compojure.api.coerce.compojure.api.resource/resource (also in compojure.api.sweet) for building resource-oriented services
(defn resource
"Creates a nested compojure-api Route from enchanced ring-swagger operations map and options.
By default, applies both request- and response-coercion based on those definitions.
Options:
- **:coercion** A function from request->type->coercion-matcher, used
in resource coercion for :body, :string and :response.
Setting value to `(constantly nil)` disables both request- &
response coercion. See tests and wiki for details.
Enchancements to ring-swagger operations map:
1) :parameters use ring request keys (query-params, path-params, ...) instead of
swagger-params (query, path, ...). This keeps things simple as ring keys are used in
the handler when destructuring the request.
2) at resource root, one can add any ring-swagger operation definitions, which will be
available for all operations, using the following rules:
2.1) :parameters are deep-merged into operation :parameters
2.2) :responses are merged into operation :responses (operation can fully override them)
2.3) all others (:produces, :consumes, :summary,...) are deep-merged by compojure-api
3) special key `:handler` either under operations or at top-level. Value should be a
ring-handler function, responsible for the actual request processing. Handler lookup
order is the following: operations-level, top-level, exception.
4) request-coercion is applied once, using deep-merged parameters for a given
operation or resource-level if only resource-level handler is defined.
5) response-coercion is applied once, using merged responses for a given
operation or resource-level if only resource-level handler is defined.
Note: Swagger operations are generated only from declared operations (:get, :post, ..),
despite the top-level handler could process more operations.
Example:
(resource
{:parameters {:query-params {:x Long}}
:responses {500 {:schema {:reason s/Str}}}
:get {:parameters {:query-params {:y Long}}
:responses {200 {:schema {:total Long}}}
:handler (fn [request]
(ok {:total (+ (-> request :query-params :x)
(-> request :query-params :y))}))}
:post {}
:handler (constantly
(internal-server-error {:reason \"not implemented\"}))})"
([info]
(resource info {}))
([info options]
(let [info (merge-parameters-and-responses info)
root-info (swaggerize (root-info info))
childs (create-childs info)
handler (create-handler info options)]
(routes/create nil nil root-info childs handler))))
[compojure "1.5.0"] is available but we use "1.4.0"
[prismatic/schema "1.1.0"] is available but we use "1.0.5"
[metosin/ring-swagger "0.22.6"] is available but we use "0.22.4"
ex-data under :response.
This can be used in logging, "what did the route try to return". Thanks to Tim Gilbert.:default code if available and response code doesn't match(GET "/" []
:responses {200 {:schema {:ping s/Str}}
:default {:schema {:error s/int}}}
...)
[prismatic/schema "1.0.5"] is available but we use "1.0.4"
:basePath with swagger-routes, thanks to Hoxu.[metosin/ring-swagger "0.22.4"] is available but we use "0.22.3"
(defn more-routes [db version]
(routes
(GET "/version" []
(ok {:version version}))
(POST "/thingie" []
(ok (thingie/create db)))))
(defn app [db]
(api
(context "/api/:version" []
:path-params [version :- s/Str]
(more-routes db version)
(GET "/kikka" []
(ok "kukka")))))
BREAKING Vanilla Compojure routes will not produce any swagger-docs (as they do not satisfy the
Routing protocol. They can still be used for handling request, just without docs.
[:api :invalid-routes-fn] to declare how to handle routes not satisfying
the Routing protocol. Default implementation logs invalid routes as WARNINGs.BREAKING compojure.core imports are removed from compojure.api.sweet:
let-request, routing, wrap-routesBREAKING Asterix (*) is removed from route macro & function names, as there is no reason to mix compojure-api & compojure route macros.
GET* => GETANY* => ANYHEAD* => HEADPATCH* => PATCHDELETE* => DELETEOPTIONS* => OPTIONSPOST* => PUTcontext* => contextdefroutes* => defroutesBREAKING swagger-docs and swagger-ui are no longer in compojure.api.sweet
:swagger (has no defaults)swagger-routes function, mounting both the swagger-ui and swagger-docs and wiring them together
/ and the swagger-spec to /swagger.jsonswagger-ui & swagger-docs (need to be separately imported from compojure.api.swagger).(defapi app
(swagger-routes)
(GET "/ping" []
(ok {:message "pong"})))
(defapi app
{:swagger {:ui "/", :spec "/swagger.json"}}
(GET "/ping" []
(ok {:message "pong"})))
BREAKING: api-level coercion option is now a function of request => type => matcher as it is documented.
Previously required a type => matcher map. Options are checked against type => matcher coercion input, and a
descriptive error is thrown when api is created with the old options format.
BREAKING: Renamed middlewares to middleware and :middlewares key (restructuring) to :middleware
BREAKING: Middleware must be defined as data: both middleware macro and :middleware restructuring take a vector of middleware containing either
[function args][[wrap-foo {:opts :bar}]][#(wrap-foo % {:opts :bar})][(fn [handler] (wrap-foo handler {:opts :bar}))]BREAKING: (Custom restructuring handlers only) :parameters key used by restructure-param
has been renamed to :swagger.
BREAKING public-resource-routes & public-resources are removed from compojure.api.middleware.
BREAKING: compojure.api.legacy namespace has been removed.
https://github.com/metosin/compojure-api/wiki/Migration-Guide-to-1.0.0
Additional route functions/macros in compojure.api.core:
routes & letroutes, just like in the Compojure, but supporting Routingundocumented - works just like routes but without any route definitions. Can be used to wrap legacy routes which setting the api option to fail on missing docs.top-level api is now just function, not a macro. It takes an optional options maps and a top-level route function.
Coercer cache is now at api-level with 10000 entries.
Code generated from restructured route macros is much cleaner now
Coercion is on by default for standalone (apiless) endpoints.
(fact "coercion is on for apiless routes"
(let [route (GET "/x" []
:query-params [x :- Long]
(ok))]
(route {:request-method :get :uri "/x" :query-params {}}) => throws))
[backtick "0.3.3"]
Fixed path parameter handling in cases where path parameter is followed by an extension (#196, metosin/ring-swagger#82)
Added compojure.api.exception/with-logging helper to add logging to exception handlers.
Updated deps:
[metosin/ring-swagger "0.22.3"] is available
[metosin/ring-swagger "0.22.2"] is available
[metosin/ring-swagger-ui "2.1.4-0"] is available
[potemkin "0.4.3"] is available
coercer-cache is now per Route instead beeing global and based on a FIFO size 100 cache. Avoids potential memory leaks when using anonymous coercion matchers (which never hit the cache).
Updated deps:
[prismatic/schema "1.0.4"] is available but we use "1.0.3"
schema & matcher -input) for better performance.
api and reading json-string out.[potemkin "0.4.2"] is available but we use "0.4.1"
[Ring-Swagger "0.22.1"]clojure.tools.logging is used with default uncaugt exception handling if it's found
on the classpath. Fixes #172.api and defapi produce identical swagger-docs. Fixes #159[metosin/ring-swagger "0.22.1"] is available but we use "0.22.0"
[metosin/ring-swagger-ui "2.1.3-4"] is available but we use "2.1.3-2"
[prismatic/plumbing "0.5.2] is available but we use "0.5.1"
ring-middleware-format accepts transit options in a new format:;; pre 0.24.0:
(api
{:format {:response-opts {:transit-json {:handlers transit/writers}}
:params-opts {:transit-json {:options {:handlers transit/readers}}}}}
...)
;; 0.24.0 +
(api
{:format {:response-opts {:transit-json {:handlers transit/writers}}
:params-opts {:transit-json {:handlers transit/readers}}}}
...)
swagger-ui now supports passing arbitrary options to SwaggerUI
(metosin/ring-swagger#67).[prismatic/schema "1.0.3"] is available but we use "0.4.4"
[prismatic/plumbing "0.5.1] is available but we use "0.4.4"
[metosin/schema-tools "0.7.0"] is available but we use "0.5.2"
[metosin/ring-swagger "0.22.0"] is available but we use "0.21.0"
[metosin/ring-swagger-ui "2.1.3-2"] is available but we use "2.1.2"
:query-params [x :- [Long]] & url ?x=1&x=2&x=3 should result in x being [1 2 3].:validation-errors :error-handler, :validation-errors :catch-core-errors?
and :exceptions :exception-handler options have been removed.
:exceptions :handlers options.context from compojure.api.sweet to compojure.api.legacy. Use context* instead.[metosin/ring-swagger "0.21.0-SNAPSHOT"] is available but we use "0.20.4"
[compojure "1.4.0"] is available but we use "1.3.4"
[prismatic/schema "0.4.4"] is available but we use "0.4.3"
[metosin/ring-http-response "0.6.5"] is available but we use "0.6.3"
[metosin/schema-tools "0.5.2"] is available but we use "0.5.1"
[metosin/ring-swagger-ui "2.1.2"] is available but we use "2.1.5-M2"
[peridot "0.4.1"] is available but we use "0.4.0"
[metosin/ring-http-response "0.6.3"] is available but we use "0.6.2"
[midje "1.7.0"] is available but we use "1.7.0-SNAPSHOT"
Optional integration with Component.
Use either :components-option of api-middleware or wrap-components-middleware
to associate the components with your API. Then you can use :components-restructuring
to destructure your components using letk syntax.
fix for #123
support for pluggable coercion, at both api-level & endpoint-level with option :coercion. See thethe tests.
ring-request->coercion-type->coercion-matcher allowing protocol-based coercion in the future
** BREAKING**: if you have created custom restructurings using src-coerce, they will break (nicely at compile-time)new restucturing :swagger just for swagger-docs. Does not do any coercion.
(GET* "/documented" []
:swagger {:responses {200 {:schema User}
404 {:schema Error
:description "Not Found"} }
:paramerers {:query {:q s/Str}
:body NewUser}}}
...)
[cheshire "5.5.0"] is available but we use "5.4.0"
[backtick "0.3.3"] is available but we use "0.3.2"
[lein-ring "0.9.6"] is available but we use "0.9.4"
:multipart-params now sets :consumes ["multipart/form-data"] and :form-params sets
:consumes ["application/x-www-form-urlencoded"]compojure.api.upload namespace.(POST* "/upload" []
:multipart-params [file :- TempFileUpload]
:middlewares [wrap-multipart-params]
(ok (dissoc file :tempfile))))
:responses. A helpful IllegalArgumentException will be thrown at compile-time with old models.:responses {400 {:schema ErrorSchema}}
:responses {400 {:schema ErrorSchema, :description "Eror"}}
api-middleware options with key :ring-swagger:(defapi app
{:ring-swagger {:ignore-missing-mappings? true}})
(swagger-docs)
(swagger-ui)
...)
path-for:(fact "bidirectional routing"
(let [app (api
(GET* "/api/pong" []
:name :pong
(ok {:pong "pong"}))
(GET* "/api/ping" []
(moved-permanently (path-for :pong))))]
(fact "path-for resolution"
(let [[status body] (get* app "/api/ping" {})]
status => 200
body => {:pong "pong"}))))
(require '[compojure.api.sweet :refer :all])
(require '[compojure.api.swagger :refer [validate])
(defrecord NonSwaggerRecord [data])
(def app
(validate
(api
(swagger-docs)
(GET* "/ping" []
:return NonSwaggerRecord
(ok (->NonSwaggerRecord "ping"))))))
; clojure.lang.Compiler$CompilerException: java.lang.IllegalArgumentException:
; don't know how to create json-type of: class compojure.api.integration_test.NonSwaggerRecord
[metosin/ring-swagger "0.20.4"] is available but we use "0.20.3"
[metosin/ring-http-response "0.6.2"] is available but we use "0.6.1"
[metosin/ring-swagger-ui "2.1.5-M2"]
[prismatic/plumbing "0.4.4"] is available but we use "0.4.3"
[prismatic/schema "0.4.3"] is available but we use "0.4.2"
with-meta), fixes #96
(context* "/responses" []
:tags ["responses"]
(GET* "/" []
:query-params [return :- (s/enum :200 :403 :404)]
:responses {403 ^{:message "spiders?"} {:code s/Str} ; old
404 (with-meta {:reason s/Str} {:message "lost?"})} ; new
:return Total
:summary "multiple returns models"
(case return
:200 (ok {:total 42})
:403 (forbidden {:code "forest"})
:404 (not-found {:reason "lost"}))))
compojure.api.core/api, the work-horse behind compojure.api.core/defapi.api, pushed to request via ring-swagger middlewares.
+compojure-api-routes+ littering the handler namespaces.[metosin/ring-swagger "0.20.3"] is available but we use "0.20.2"
[prismatic/plumbing "0.4.3"] is available but we use "0.4.2"
[peridot "0.4.0"] is available but we use "0.3.1"
[compojure "1.3.4"] is available but we use "1.3.3"
[lein-ring "0.9.4"] is available but we use "0.9.3"
[metosin/ring-swagger "0.20.2"] is available but we use "0.20.0"
[prismatic/schema "0.4.2"] is available but we use "0.4.1"
New restructuring for :no-doc (a boolean) - endpoints with this don't get api documentation.
Fixed #42 - defroutes* now does namespace resolution for the source
used for route peeling and source linking (the macro magic)
Fixed #91 - defroutes* are now automatically accessed over a Var for better development flow.
Fixed #89.
Fixed #82.
Fixed #71, ring-swagger-ui is now a dependency.
breaking ring.swagger.json-schema/describe is now imported into compojure.api.sweet for easy use. If your code
refers to it directly, you need remove the direct reference.
defapi or compojure.api.routes/api-root within that)compojure.api.routes/with-routes is now compojure.api.routes/api-root[metosin/ring-swagger-ui "2.1.1-M2"] to get things pre-configured2.1.1-M2 yourself from the source.:nickname is now :operationId:notes is now :descriptionswagger-docs now takes any valid Swagger Spec data in. Using old format gives a warning is to STDOUT.(swagger-docs
{:info {:version "1.0.0"
:title "Sausages"
:description "Sausage description"
:termsOfService "http://helloreverb.com/terms/"
:contact {:name "My API Team"
:email "foo@example.com"
:url "http://www.metosin.fi"}
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}}
:tags [{:name "kikka", :description "kukka"}]})
/api/api-docs to /swagger.json.compojure.api.swagger/swaggered is deprecated - not relevant with 2.0. Works, but prints out a warning to STDOUT
** in 2.0, apis are categorized by Tags, one can set them either to endpoints or to paths:(GET* "/api/pets/" []
:tags ["pet"]
(ok ...))
(context* "/api/pets" []
:tags ["pet"]
(GET* "/" []
:summary "get all pets"
(ok ...)))
[metosin/ring-swagger "0.20.0"] is available but we use "0.19.4"
[prismatic/schema "0.4.1"] is available but we use "0.4.0"
[prismatic/plumbing "0.4.2"] is available but we use "0.4.1"
[prismatic/schema "0.4.1"] is available but we use "0.4.0"
[potemkin "0.3.13"] is available but we use "0.3.12"
[compojure "1.3.3"] is available but we use "1.3.2"
[metosin/ring-swagger "0.19.4"] is available but we use "0.19.3"
2.1.0-M2 - [metosin/ring-swagger-ui "2.1.0-M2-2][metosin/ring-swagger "0.19.3"] is available but we use "0.19.2"
:return (s/maybe User)
:responses {200 (s/maybe User)
400 (s/either Cat Dog)}
[metosin/ring-swagger "0.19.2"] is available but we use "0.19.1"
:headers, thanks to tchagnon!:path-param allows any keywords, needed for the partial parameter matching with context*compojure.api.meta/restructure-param dispatch functions - for the swagger documentation part. See https://github.com/metosin/ring-swagger/blob/master/test/ring/swagger/swagger2_test.clj & https://github.com/metosin/compojure-api/blob/master/src/compojure/api/meta.clj for examples of the new schemas.context* to allow setting meta-data to mid-routes. Mid-route meta-data are deep-merged into endpoint swagger-definitions at compile-time. At runtime, code is executed in place.(context* "/api/:kikka" []
:summary "summary inherited from context"
:path-params [kikka :- s/Str] ; enforced here at runtime
:query-params [kukka :- s/Str] ; enforced here at runtime
(GET* "/:kakka" []
:path-params [kakka :- s/Str] ; enforced here at runtime
(ok {:kikka kikka
:kukka kukka
:kakka kakka})))
[prismatic/plumbing "0.4.1"] is available but we use "0.3.7"
[potemkin "0.3.12"] is available but we use "0.3.11"
[prismatic/schema "0.4.0"] is available but we use "0.3.7"
[metosin/ring-http-response "0.6.1"] is available but we use "0.6.0"
[metosin/ring-swagger "0.19.0"] is available but we use "0.18.1"
[lein-ring "0.9.3"] is available but we use "0.9.2"
(defapi app
{:format {:formats [:json-kw :yaml-kw :edn :transit-json :transit-msgpack]
:params-opts {}
:response-opts {}}
:validation-errors {:error-handler nil
:catch-core-errors? nil}
:exceptions {:exception-handler default-exception-handler}}
...)
compojure.core/wrap-routes into compojure.api.sweetcompojure.api.middleware, ex-info-support is now parameterizable wrap-exception
[prismatic/plumbing "0.3.7"] is available but we use "0.3.5"
[compojure "1.3.2"] is available but we use "1.3.1"
[prismatic/schema "0.3.7"] is available but we use "0.3.3"
[metosin/ring-swagger "0.18.0"] is available but we use "0.15.0"
[metosin/ring-http-response "0.6.0"] is available but we use "0.5.2"
[metosin/ring-middleware-format "0.6.0"] is available but we use "0.5.0"
ring-middleware-format
[cheshire "5.4.0"] is available but we use "5.3.1"
[metosin/ring-swagger-ui "2.0.24"] is available but we use "2.0.17"
[lein-ring "0.9.0"] is available but we use "0.8.13"
[compojure "1.3.1"] is available but we use "1.2.1"
[metosin/ring-swagger "0.15.0"] is available but we use "0.14.1"
[peridot "0.3.1"] is available but we use "0.3.0"
[prismatic/schema "0.3.3"] is available but we use "0.3.2"
[metosin/ring-http-response "0.5.2"] is available but we use "0.5.1"
[org.tobereplaced/lettercase "1.0.0"] for camel-casing (see https://github.com/metosin/compojure-api-examples/issues/1#issuecomment-62580504)[metosin/ring-swagger "0.14.1"] is available but we use "0.14.0"
:form-parameters, thanks to Thomas Whitcomb[prismatic/plumbing "0.3.5"] is available but we use "0.3.3"
[potemkin "0.3.11"] is available but we use "0.3.8"
[compojure "1.2.1"] is available but we use "1.1.9"
[prismatic/schema "0.3.2"] is available but we use "0.2.6"
[metosin/ring-http-response "0.5.1"] is available but we use "0.5.0"
[metosin/ring-swagger "0.14.0"] is available but we use "0.13.0"
[lein-ring "0.8.13"] is available but we use "0.8.11"
:middlewares broke route parameters:yaml-in-html and :clojure from default response formatsclojure.walkring-swaggerring-swagger
hash-map loses the order if it has enough properties(s/defschema Thingie (ordered-map :a String ...))~~ring-swagger:body and others no langer take description as third param, instead use :body [body (describe Schema "The description")]
describe works also for Java classes :query-params [x :- (describe Long "first-param")](s/defschema Schema {:sub (describe [{:x Long :y String}] "Array of stuff")})500 instead of 400, thanks to @phadej!(GET* "/plus" []
:return Long
:query-params [x :- Long {y :- Long 1}]
:summary "x+y with query-parameters. y defaults to 1."
(ok (+ x y)))
:responses restructuring to (error) return codes and models, thanks to @phadej!(POST* "/number" []
:return Total
:query-params [x :- Long y :- Long]
:responses {403 ^{:message "Underflow"} ErrorEnvelope}
:summary "x-y with body-parameters."
(let [total (- x y)]
(if (>= total 0)
(ok {:total (- x y)})
(forbidden {:message "difference is negative"}))))
s/Uuid via latest ring-swagger.compojure.api.meta/restructure-param:header-params (fixes #31)[metosin/ring-swagger 0.10.2])
String is supported as Ring doesn't support others
swagger atom, there is one defined +routes+ var per namespace
compojure.api.core/with-routes on api root to generate and hold the +routes+ (automatically bundled with defapi)0.10.1 to get support for s/Keyword as a nested schema key.middlewares macro and :middlewares restructuring now use thread-first to apply middlewares0.9.1 with support for vanilla schema.core/defschema schemas
defroutes to compojure.api.legacycompojure.api.common: ->Long, fn->, fn->>compojure.api.meta/restructure (doesn't generate empty lets & letks)compojure.api.legacy ns to have the old Compojure HTTP-method macros (GET, POST,...)[prismatic/plumbing "0.3.1"] is available but we use "0.2.2"
[compojure "1.1.8"] is available but we use "1.1.7"
[prismatic/schema "0.2.3"] is available but we use "0.2.2"
[metosin/ring-swagger "0.8.8"] is available but we use "0.8.7"
[peridot "0.3.0"] is available but we use "0.2.2"
[metosin/ring-swagger "0.8.7"][metosin/ring-swagger-ui "2.6.16-2"]updated dependencies:
[compojure "1.1.7"][prismatic/schema "0.2.2"][metosin/ring-swagger "0.8.5"]consumes and produces are now feed to ring-swagger based on the installed middlewares.
restructure-param to receive key, value and the accumulator. Remove the key from accumulator parameters by default. No more alpha.meta:middlewares restructuring to support adding middlewares to routes: (DELETE* "/user/:id" []
:middlewares [audit-support (for-roles :admin)]
(ok {:name "Pertti"})))
with-middleware is renamed to middlewares & it applies middlewares in reverse orderclojure.walk16 internallyclojure.walk to clojure.walk16swagger atom happens now at runtime, not compile-time. Works with AOT.compojure.api.core restructuring are now using restructure-param multimethod to allow external extensions. ALPHA.swaggered resources are now collected in order+compojure-api-request+ when having both Compojure destructuring & Compojure-api destructuring in place:body-params (with strict schema):(POST* "/minus" []
:body-params [x :- Long y :- Long]
:summary "x-y with body-parameters"
(ok {:total (- x y)}))
ring-swagger to 0.8.4 to get better basepath-resolution (with reverse-proxies):path-parameters and query-parameters:(GET* "/sum" []
:query-params [x :- Long y :- Long]
:summary "sums x & y query-parameters"
(ok {:total (+ x y)}))
(GET* "/times/:x/:y" []
:path-params [x :- Long y :- Long]
:summary "multiplies x & y path-parameters"
(ok {:total (* x y)}))
swagger-ui index-redirect work also under a context when running in an legacy app-server. Thanks to Juha Syrjälä for the PR.instanceof? to match records instead of = with class. Apps can now be uberwarred with lein ring uberwar.ring-swagger to 0.8.3, generate path-parameters on client sidering-swagger to 0.8.1, all JSON-schema generation now done there.ring-http-response to 0.4.0compojure.api.core-integration-test using peridot.core(context "/api" []
(GET* ["/item/:name" :name #"[a-z/]+"] [name] identity))
GET* and POST*. Addeds tests to verify.ring-swagger to 0.7.3 (GET* "/echo" []
:return Thingie
:query [thingie Thingie]
(ok thingie)) ;; here be coerced thingie
compojure.api.routes/defroutes is now compojure.api.core/defroutes* to avoid namespace clashes & promote it's different.compojure.api.core web methods"compojure.api.core.Ring-Swagger to 0.7.2json-response-support, thanks to Dmitry BalakhonskiyRing-Swagger to 0.7.1 giving support for nested Maps: (defmodel Customer {:id String
:address {:street String
:zip Long
:country {:code Long
:name String}}})
compojure.api.core web methods does now automatic coercion for the bodycompojure.api.core web methods (POST* "/customer"
:return Customer
:body [customer Customer]
(ok customer))) ;; we have a coerced customer here
ring-swagger to 0.7.0
schema/maybe and schema/bothDate & DateTime both with and without milliseconds: "2014-02-18T18:25:37.456Z" & "2014-02-18T18:25:37Z"swaggered is stripped out of spaces.ring-swagger to 0.6.0
swaggered doesn't have to contain container-element (context etc.) within, endpoints are ok: (swaggered "ping"
:description "Ping api"
(GET* "/ping" [] (ok {:ping "pong"})))
POST* and PUT* now allows model sequences: (POST* "/pizzas" []
:body [pizzas [NewPizza] {:description "new pizzas"}]
(ok (add! pizzas)))
ring-swagger to 0.5.0 to get support for Data & DateTime.swaggered can now follow symbols pointing to a compojure.api.routes/defroutes route definition to allow better route composition.compojure.api.sweet now uses compojure.api.routes/defroutes instead of compojure.core/defroutesCan you improve this documentation? These fine people already did:
Tommi Reiman, Juho Teperi, Ambrose Bonnaire-Sergeant, Miikka Koskinen, Anton Oellerer & Daniel KwiecinskiEdit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |