[[responses]]
== Responses

In resource interactions, a request is processed by a method, usually
resulting in a response. The response contains a status code, headers
and a body.

yada attempts to set the correct status code and headers according to
the semantics of both the method and mime-type. It also coerces the
result of a method into the response body if necessary.

Sometimes, however, the response returned by yada is not what you want.
There are times that you want more fine-grained control, want to provide
custom bodies for certain status codes (such as 404 errors), or want
deviate from the HTTP standards entirely.

[[explicit-responses]]
=== Explicit responses

When you need _complete control_ over the response you should return the
**request-context**'s response, modified if necessary. In which case
yada will see that you want to be explicit and get out of your way.

[source,clojure]
----
(fn [ctx]
 (let [response (:response ctx)]
  ;; return a response, explicitly associating
  ;; (or updating) the status, headers or body.
  (update-in response […] …)
 ))
----

[[declared-responses]]
=== Declared responses

yada declares the responses that may normally be produced by a method.
It adds these declarations to the *resource-model* when creating a
resource prior to processing.

However, with explicit responses you may generate response codes that
are unexpected by yada and which could be declared through the
**resource-model**.

In these cases, you should declare the response codes in the
*:responses* entry of the resource's **resource-model**.

[source,clojure]
----
{:responses
 {418 {:description "I'm a teapot"}}}
----

The keys in the *:responses* map can be integers, sets of integers, or
the wildcard: `*`. Only sets are supported, so if you need to produce a
range of status codes, create a set programmatically:

[source,clojure]
----
{(set (concat (range 400 404) (range 405 500))}
 {:description "All errors besides 404"
  …
  }}
----

Individual status codes take precedence over sets of status codes, which
take precedence over wildcards. After that, the order in which keys are
checked is undefined. If you are using sets, avoid declaring the same
status code in multiple keys.

[[status-responses]]
=== Status responses

Usually yada will return the responses produced by methods, and create
ones for errors that occur along the way.

Often it is useful to be able to control the response body, or even the
complete response, for responses with certain status codes.

We can specify these controlled responses by specifying a response entry
in the value corresponding to the status code.

A common example is providing a custom 404 page when a resource cannot
be found, which may provide the user with details of why the resource
couldn't be found and perhaps what to do next.

Let's see how this is done:

[source,clojure]
----
(require '[yada.yada :as yada])

{:properties {:exists? false}

 :responses
 {404 {:description "Not found"
       :produces #{"text/html" "text/plain;q=0.9"}
       :response (let [msg "Oh dear I couldn't find that"]
                   (fn [ctx]
                     (case (yada/content-type ctx)
                       "text/html" (html [:h2 msg])
                       (str msg \newline))))}}}
----

Note that the response definition can include a declaration of the
representations that the response can produce.

If the response is caused by an error, the actual error is available in
the context under **:error**.
