├── .gitignore ├── project.clj ├── README.md └── src └── compojure └── api └── examples ├── domain.clj └── handler.clj /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /classes 3 | /checkouts 4 | pom.xml 5 | pom.xml.asc 6 | *.jar 7 | *.class 8 | /.lein-* 9 | /.nrepl-port 10 | .project 11 | .settings -------------------------------------------------------------------------------- /project.clj: -------------------------------------------------------------------------------- 1 | (defproject metosin/compojure-api-examples "1.1.0" 2 | :description "Compojure-api-examples" 3 | :dependencies [[org.clojure/clojure "1.10.3"] 4 | [metosin/compojure-api "1.1.13"]] 5 | :ring {:handler compojure.api.examples.handler/app} 6 | :uberjar-name "examples.jar" 7 | :uberwar-name "examples.war" 8 | :profiles {:dev {:dependencies [[javax.servlet/javax.servlet-api "4.0.1"]] 9 | :plugins [[lein-ring "0.12.6"]]}}) 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Compojure-api-examples 2 | 3 | Example project for using [Compojure-api](https://github.com/metosin/compojure-api). 4 | 5 | ## Usage 6 | 7 | ### Running 8 | 9 | `lein ring server` 10 | 11 | ### Packaging and running as standalone jar 12 | 13 | ``` 14 | lein do clean, ring uberjar 15 | java -jar target/examples.jar 16 | ``` 17 | 18 | ### Packaging as war 19 | 20 | `lein ring uberwar` 21 | 22 | ## License 23 | 24 | Copyright © 2014-2015 [Metosin Oy](http://www.metosin.fi) 25 | 26 | Distributed under the Eclipse Public License, the same as Clojure. 27 | -------------------------------------------------------------------------------- /src/compojure/api/examples/domain.clj: -------------------------------------------------------------------------------- 1 | (ns compojure.api.examples.domain 2 | (:require [schema.core :as s] 3 | [ring.swagger.schema :refer [coerce!]])) 4 | 5 | ;; Domain 6 | 7 | (s/defschema Total {:total Long}) 8 | 9 | (def Topping (s/enum :cheese :olives :ham :pepperoni :habanero)) 10 | 11 | (s/defschema Pizza {:id Long 12 | :name String 13 | :price Double 14 | :hot Boolean 15 | (s/optional-key :description) String 16 | :toppings #{Topping}}) 17 | 18 | (s/defschema NewPizza (dissoc Pizza :id)) 19 | 20 | (s/defschema NewSingleToppingPizza (assoc NewPizza :toppings Topping)) 21 | 22 | ;; Repository 23 | 24 | (defonce id-seq (atom 0)) 25 | (defonce pizzas (atom (array-map))) 26 | 27 | (defn get-pizza [id] (@pizzas id)) 28 | (defn get-pizzas [] (-> pizzas deref vals reverse)) 29 | (defn delete! [id] (swap! pizzas dissoc id) nil) 30 | 31 | (defn add! [new-pizza] 32 | (let [id (swap! id-seq inc) 33 | pizza (coerce! Pizza (assoc new-pizza :id id))] 34 | (swap! pizzas assoc id pizza) 35 | pizza)) 36 | 37 | (defn update! [pizza] 38 | (let [pizza (coerce! Pizza pizza)] 39 | (swap! pizzas assoc (:id pizza) pizza) 40 | (get-pizza (:id pizza)))) 41 | 42 | ;; Data 43 | 44 | (when (empty? @pizzas) 45 | (add! {:name "Frutti" :price 9.50 :hot false :toppings #{:cheese :olives}}) 46 | (add! {:name "Il Diablo" :price 12 :hot true :toppings #{:ham :habanero}})) 47 | -------------------------------------------------------------------------------- /src/compojure/api/examples/handler.clj: -------------------------------------------------------------------------------- 1 | (ns compojure.api.examples.handler 2 | (:require [compojure.api.sweet :refer :all] 3 | [ring.util.http-response :refer :all] 4 | [compojure.api.examples.domain :refer :all] 5 | [schema.core :as s])) 6 | 7 | (def app 8 | (api 9 | {:swagger 10 | {:ui "/" 11 | :spec "/swagger.json" 12 | :data {:info {:title "Sample Api" 13 | :description "Compojure Api sample application"} 14 | :tags [{:name "math", :description "math with parameters"} 15 | {:name "echo", :description "request echoes"} 16 | {:name "pizza", :description "pizza Api it is."}]}}} 17 | 18 | (context "/math" [] 19 | :tags ["math"] 20 | 21 | (GET "/plus" [] 22 | :return Total 23 | :query-params [x :- Long, y :- Long] 24 | :summary "x+y with query-parameters" 25 | (ok {:total (+ x y)})) 26 | 27 | (POST "/minus" [] 28 | :return Total 29 | :body-params [x :- Long, y :- Long] 30 | :summary "x-y with body-parameters" 31 | (ok {:total (- x y)})) 32 | 33 | (GET "/times/:x/:y" [] 34 | :return Total 35 | :path-params [x :- Long, y :- Long] 36 | :summary "x*y with path-parameters" 37 | (ok {:total (* x y)})) 38 | 39 | (GET "/power" [] 40 | :return Total 41 | :header-params [x :- Long, y :- Long] 42 | :summary "x^y with header-parameters" 43 | (ok {:total (long (Math/pow x y))}))) 44 | 45 | (context "/echo" [] 46 | :tags ["echo"] 47 | 48 | (GET "/request" req 49 | (ok (dissoc req :body))) 50 | 51 | (GET "/pizza" [] 52 | :return NewSingleToppingPizza 53 | :query [pizza NewSingleToppingPizza] 54 | :summary "get echo of a pizza" 55 | (ok pizza)) 56 | 57 | (PUT "/anonymous" [] 58 | :return [{:secret Boolean s/Keyword s/Any}] 59 | :body [body [{:secret Boolean s/Keyword s/Any}]] 60 | (ok body)) 61 | 62 | (GET "/hello" [] 63 | :return String 64 | :query-params [name :- String] 65 | (ok (str "Hello, " name))) 66 | 67 | (POST "/pizza" [] 68 | :return NewSingleToppingPizza 69 | :body [pizza NewSingleToppingPizza] 70 | :summary "post echo of a pizza" 71 | (ok pizza))) 72 | 73 | (context "/pizzas" [] 74 | :tags ["pizza"] 75 | 76 | (GET "/" [] 77 | :return [Pizza] 78 | :summary "Gets all Pizzas" 79 | (ok (get-pizzas))) 80 | 81 | (POST "/" [] 82 | :return Pizza 83 | :body [pizza NewPizza {:description "new pizza"}] 84 | :summary "Adds a pizza" 85 | (ok (add! pizza))) 86 | 87 | (PUT "/" [] 88 | :return Pizza 89 | :body [pizza Pizza] 90 | :summary "Updates a pizza" 91 | (ok (update! pizza))) 92 | 93 | (GET "/:id" [] 94 | :return Pizza 95 | :path-params [id :- Long] 96 | :summary "Gets a pizza" 97 | (ok (get-pizza id))) 98 | 99 | (DELETE "/:id" [] 100 | :path-params [id :- Long] 101 | :summary "Deletes a Pizza" 102 | (ok (delete! id)))))) 103 | --------------------------------------------------------------------------------