Skip to content

Latest commit

 

History

History
166 lines (122 loc) · 4.34 KB

response.md

File metadata and controls

166 lines (122 loc) · 4.34 KB

Response

This guide outlines how to use the response map to respond to incoming requests.

Coast passes the current HTTP response map as part of the request-lifecycle which is sent to all route handlers and middleware.

; routes.clj
(def routes
  (coast/routes
    [:get "/" :home/index]))

; src/home.clj
(defn index [request]
  {:status 200 :body "this returns a string"})

The above example returns a string with a content type of text/plain

Basic Example

The following example returns an array of customers in JSON format:

; routes.clj
[:get "/customers" :customer/index]

; src/customer.clj
(defn index [request]
  (let [customers [{:customer/id 1 :customer/name "Sean"}
                   {:customer/id 2 :customer/name "Johnny"}
                   {:customer/id 2 :customer/name "Felix"}
                   {:customer/id 2 :customer/name "Gloria"}]]
    {:status 200 :body customers :headers {"Content-Type" "application/json"}}))

The coast/ok function can also be used instead of a map:

(defn index [request]
  (let [customers [{:customer/id 1 :customer/name "Sean"}
                   {:customer/id 2 :customer/name "Johnny"}
                   {:customer/id 2 :customer/name "Felix"}
                   {:customer/id 2 :customer/name "Gloria"}]]
    (coast/ok customers :json)))

Making responses

Coast has common functions for the most common http responses:

  • ok (200)
  • created (201)
  • accepted (202)
  • no-content (204)
  • bad-request (400)
  • unauthorized (401)
  • not-found (404)
  • forbidden (403)
  • server-error 500

They accept either a keyword as the last argument, :html or :json.

(coast/created {:customer/id 1} :json)

(coast/ok [:h1 "hello world"] :html)

Headers

They also accept headers as well:

(coast/created {:customer/id 1} {"Content-Type" "application/json"})

(coast/ok [:h1 "hello world"] {"Content-Type" "text/html"})

Coast by default returns {"Content-Type" "application/octet-stream"}

Cookies

Use the following keys to set/remove response cookies.

cookie

Set a cookie value:

{:status 200
 :body ""
 :cookies {"cart-total" {:value "20"}}}

clearing a cookie

Remove an existing cookie value (by setting its expiry in the past):

{:status 200
 :body ""
 :cookies {"cart-total" {:expires (coast/time 1 :second/ago)}}}

As well as setting the value of the cookie, you can also set additional keys:

Shamelessly stolen from the ring docs

  • :domain - restrict the cookie to a specific domain
  • :path - restrict the cookie to a specific path
  • :secure - restrict the cookie to HTTPS URLs if true
  • :http-only - restrict the cookie to HTTP if true (not accessible via e.g. JavaScript)
  • :max-age - the number of seconds until the cookie expires
  • :expires - a specific date and time the cookie expires
  • :same-site - Specify :strict or :lax to determine whether cookies should be sent with cross-site requests

Redirects

Use one of the following functions to redirect requests to a different URL.

redirect

Redirect request to a different url (by default it will set the status as 302):

(defn view [request])

(defn create [request]
  (coast/redirect (coast/url-for ::view)))

You can also skip the url-for like so:

(defn create [request]
  (coast/redirect-to ::view))

Or you can redirect to any url:

(coast/redirect "https://coastonclojure.com")

flash

Coast also has a handy flash function which will append a value to the next request after the redirect:

(-> (coast/redirect-to ::view)
    (coast/flash "Item created successfully!"))

This flash value now resides in the next function's request map under the :flash key

Extending Response

It is also possible to extend the response map by adding your own keys:

(defn index [request])
  (-> (coast/ok "Annie are you ok, are you ok, Annie?")
      (assoc :my-custom-key-for-my-custom-middleware "hello")