# Compojure-api **Psst!** If you're starting a new project, why not try out [reitit](https://github.com/metosin/reitit)? Stuff on top of [Compojure](https://github.com/weavejester/compojure) for making sweet web apis. - [Schema](https://github.com/Prismatic/schema) & [clojure.spec](https://clojure.org/about/spec) (2.0.0) for input & output data coercion - [Swagger](http://swagger.io/) for api documentation, via [ring-swagger](https://github.com/metosin/ring-swagger) & [spec-tools](https://github.com/metosin/spec-tools) - [Async](https://github.com/metosin/compojure-api/wiki/Async) with async-ring, [manifold](https://github.com/ztellman/manifold) and [core.async](https://github.com/clojure/core.async) (2.0.0) - Client negotiable formats: [JSON](http://www.json.org/), [EDN](https://github.com/edn-format/edn) & [Transit](https://github.com/cognitect/transit-format), optionally [YAML](http://yaml.org/) and [MessagePack](http://msgpack.org/) - Data-driven [resources](https://github.com/metosin/compojure-api/wiki/Resources-and-Liberator) - [Bi-directional](https://github.com/metosin/compojure-api/wiki/Routing#bi-directional-routing) routing - Bundled middleware for common api behavior ([exception handling](https://github.com/metosin/compojure-api/wiki/Exception-handling), parameters & formats) - Extendable route DSL via [metadata handlers](https://github.com/metosin/compojure-api/wiki/Creating-your-own-metadata-handlers) - Route functions & macros for putting things together, including the [Swagger-UI](https://github.com/wordnik/swagger-ui) via [ring-swagger-ui](https://github.com/metosin/ring-swagger-ui) - Requires Clojure 1.9.0 & Java 1.8 [API Docs](http://metosin.github.io/compojure-api/doc/) & [Wiki](https://github.com/metosin/compojure-api/wiki) ## Latest version [![Clojars Project](http://clojars.org/metosin/compojure-api/latest-version.svg)](http://clojars.org/metosin/compojure-api) Latest non-alpha: `[metosin/compojure-api "1.1.14"]`. See [CHANGELOG](https://github.com/metosin/compojure-api/blob/master/CHANGELOG.md) for details. ## For information and help ### [Read the Version 1.0 Blog Post](http://www.metosin.fi/blog/compojure-api-100/) ### [Schema & Spec Coercion with 2.0.0](https://github.com/metosin/compojure-api/wiki/Coercion) ### [Check wiki for documentation](https://github.com/metosin/compojure-api/wiki) [Clojurians slack](https://clojurians.slack.com/) ([join](http://clojurians.net/)) has a channel [#ring-swagger](https://clojurians.slack.com/messages/ring-swagger/) for talk about any libraries using Ring-swagger. You can also ask questions about Compojure-api and Ring-swagger on other channels at Clojurians Slack or at #clojure on Freenode IRC (mention `compojure-api` or `ring-swagger` to highlight us). ## Examples ### Hello World Api ```clj (require '[compojure.api.sweet :refer :all]) (require '[ring.util.http-response :refer :all]) (def app (api (GET "/hello" [] :query-params [name :- String] (ok {:message (str "Hello, " name)})))) ``` ### Hello World, async ```clj (require '[compojure.api.sweet :refer :all]) (require '[clojure.core.async :as a]) (GET "/hello-async" [] :query-params [name :- String] (a/go (a/* requires server to be run in [async mode](https://github.com/metosin/compojure-api/wiki/Async) ### Hello World, async & data-driven ```clj (require '[compojure.api.sweet :refer :all]) (require '[clojure.core.async :as a]) (require '[schema.core :as s]) (context "/hello-async" [] (resource {:get {:parameters {:query-params {:name String}} :responses {200 {:schema {:message String}} 404 {} 500 {:schema s/Any}} :handler (fn [{{:keys [name]} :query-params}] (a/go (a/* Note that empty body responses can be specified with `{}` or `{:schema s/Any}` ### Hello World, async, data-driven & clojure.spec ```clj (require '[compojure.api.sweet :refer :all]) (require '[clojure.core.async :as a]) (require '[clojure.spec.alpha :as s]) (s/def ::name string?) (s/def ::message string?) (context "/hello-async" [] (resource {:coercion :spec :get {:parameters {:query-params (s/keys :req-un [::name])} :responses {200 {:schema (s/keys :req-un [::message])}} :handler (fn [{{:keys [name]} :query-params}] (a/go (a/