[[parameters-chapter]]
== Parameters

As we learned in <<parameters-intro>>, ((parameters)) declarations are useful to validate and coerce request parameters, produce 400 status responses on bad requests thereby providing some protection against bad input data.

Many requests embed parameters in their URIs. For example, let's imagine a URI to access the transactions of a fictitious bank account.

....
https://bigbank.com/accounts/1234/transactions?since=tuesday
....

There could be 2 parameters here. The first, `1234`, is contained in the
path `/accounts/1234/transactions`. We call this a **path parameter**.

The second, `tuesday`, is embedded in the URI's query-string (after the
`?` symbol). We call this a **query parameter**.

You can declare these parameters in the **resource model**.

[source,clojure]
----
{:parameters {:path {:entry Long}}
 :methods {:get {:parameters {:query {:since String}}}
           :post {:parameters {:body …}}}
----

Parameters can be specified at _resource-level_ or at __method-level__.
Path parameters are usually declared at the resource-level because they
form part of the URI that is independent of the request's method. In
contrast, query parameters usually apply to GET requests, so it's common
to define this parameter at the __method-level__, and it's only visible
if the method we declare it with matches the request method.

We declare parameter values using the syntax of
https://github.com/plumatic[Plumatic]'s
https://github.com/plumatic/schema[schema] library. This allows us to
get quite sophisticated in how we define parameters.

[source,clojure]
----
(require [schema.core :refer (defschema)]

(defschema Transaction
  {:payee String
   :description String
   :amount Double}

{:parameters {:path {:entry Long}}
 :methods {:get {:parameters {:query {:since String}}}
           :post {:parameters {:body Transaction}}}
----

[[capturing-multi-value-parameters]]
=== Capturing multi-value parameters

Occasionally, you may have multiple values associated with a given
parameter. Query strings and HTML form data both allow for the same
parameter to be specified multiple times.

....
/search?accno=1234&accno=1235
....

To capture all values in a vector, declare your parameter type as a
vector type:

[source,clojure]
----
{:parameters {:query {:accno [Long]}}}}
----

[[capturing-large-request-bodies]]
=== Capturing large request bodies

Sometimes, request bodies are very large or even unlimited. To ensure
you don't run out of memory receiving this request data, you can specify
more suitable containers, such as files, database blobs, Amazon S3
buckets or your own extensions.

All data produced and received from yada is handled efficiently and
asynchronously, ensuring that even with very large data streams your
service continues to work.

[source,clojure]
----
{:parameters {:form {:video java.io.File}}}
----
