Requests & Responses

Contents

  1. Requests and Responses
  2. Overview
  3. Requests
  4. Responses
  5. Response encoding
  6. Setting headers
  7. Setting content type
  8. Setting custom status
  9. Redirects

Requests and Responses

Overview

The base reitit ring handler uses the environmental middleware and the ring.middleware.defaults default middleware as configured in your system.edn.

On top of this, the default generated api routes in Kit use the following middleware configuration. They are found in your <<project-ns>>.web.routes.api

[;; query-params & form-params
parameters/parameters-middleware
;; content-negotiation
muuntaja/format-negotiate-middleware
;; encoding response body
muuntaja/format-response-middleware
;; exception handling
coercion/coerce-exceptions-middleware
;; decoding request body
muuntaja/format-request-middleware
;; coercing response bodys
coercion/coerce-response-middleware
;; coercing request parameters
coercion/coerce-request-middleware
;; exception handling
exception/wrap-exception]

This configuration handles request and response parameter coercion, exception handling.

Requests

By default the request parameters, such as those from a form POST, will be automatically parsed and set as a :params key on the request.

The request parameters will be available under the :params key of the request. Note that the middleware will also handle encoding the response bodies when you set the appropriate MIME type on the response.

Responses

Ring responses are generated using the ring-http-response library. The library provides a number of helpers for producing responses with their respective HTTP Status codes.

For example, the ring.util.http-response/ok helper is used to generate a response with the status 200. The following code will produce a valid response map with the content set as its :body key.

(ok {:foo "bar"})

;;result of calling response
{:status  200
 :headers {}
 :body    {:foo "bar"}}

The response body can be one of a string, a sequence, a file, or an input stream. The body must correspond appropriately with the response's status code.

A string, it will be sent back to the client as is. For a sequence, a string representing each element is sent to the client. Finally, if the response is a file or an input stream, then the server sends its contents to the client.

Response encoding

By default, the muuntaja middleware library is used to infer the response type when a route returns a map containing the :body key:

{:body {:foo "bar"}}

The middleware is found in the <project-ns>.web.middleware.formats namespace of your application:

(ns <project-ns>.web.middleware.formats
  (:require
    [luminus-transit.time :as time]
    [muuntaja.core :as m]))

(def instance
  (m/create
    (-> m/default-options
        (update-in
          [:formats "application/transit+json" :decoder-opts]
          (partial merge time/time-deserialization-handlers))
        (update-in
          [:formats "application/transit+json" :encoder-opts]
          (partial merge time/time-serialization-handlers)))))

Muuntaja will use the Content-Type header to infer the content of the request, and the Accept header to infer the response format.

By default we can see we already have some time serialization and deserialization handlers provided by luminus-transit.time to help us with reader and writing Java time objects.

Setting headers

Setting additional response headers is done by calling ring.util.http-response/header, and passing it a map of HTTP headers. Note that the keys must be strings.

(-> "hello world" response (header "x-csrf" "csrf"))

Setting content type

You can set a custom response type by using the ring.util.http-response/content-type function, eg:

(defn project-handler [req]
  (-> (clojure.java.io/input-stream "report.pdf")
      (ok)
      (content-type "application/pdf")))

Setting custom status

Setting a custom status is accomplished by passing the content to the ring.util.http-response/status function:

(defn missing-page [req]
  (-> "your page could not be found"
      (ok)
      (status 404)))

Redirects

Redirects are handled by the ring.util.http-response/found function. The function will set a 302 redirect status on the response.

(defn old-location []
  (found "/new-location"))

Please refer to the ring-http-response to see other available helpers.