@@@ div { .group-java }

The `formFields` directive is not available for Java, see @ref[formField](formField.md) and @ref[formFieldList](formFieldSeq.md).

@@@

@@@ div { .group-scala }
# formFields

## Signature

```scala
def formFields(field: <FieldDef[T]>): Directive1[T]
def formFields(fields: <FieldDef[T_i]>*): Directive[T_0 :: ... T_i ... :: HNil]
def formFields(fields: <FieldDef[T_0]> :: ... <FieldDef[T_i]> ... :: HNil): Directive[T_0 :: ... T_i ... :: HNil]
```

The signature shown is simplified and written in pseudo-syntax, the real signature uses magnets. <a id="^1" href="#1">[1]</a> The type
`<FieldDef>` doesn't really exist but consists of the syntactic variants as shown in the description and the examples.

> <a id="1" href="#^1">[1]</a> See [The Magnet Pattern](https://web.archive.org/web/20240311111722/http://spray.io/blog/2012-12-13-the-magnet-pattern/) for an explanation of magnet-based overloading.

## Description

Extracts fields from requests generated by HTML forms (independently of @apidoc[HttpMethod] used).

Form fields can be either extracted as a String or can be converted to another type. The parameter name
can be supplied either as a String or as a Symbol. Form field extraction can be modified to mark a field
as required, optional, or repeated, or to filter requests where a form field has a certain value:

`"color"`
: extract the value of field "color" as `String`
: reject if the field is missing

`"color".optional`
: (symbolic notation `"color".?`)
: extract the optional value of field "color" as `Option[String]`

`"color".withDefault("red")`
: (symbolic notation `"color" ? "red"`)
: extract the optional value of field "color" as `String` with default value `"red"`

`"color".requiredValue("blue")`
: (symbolic notation `"color" ! "blue"`)
: require the value of field "color" to be `"blue"` and extract nothing
: reject if the field is missing or can't be unmarshalled to the given type

`"amount".as[Int]`
: extract the value of field "amount" as `Int`, you need a matching implicit @apidoc[Unmarshaller] in scope for that to work
(see also @ref[Unmarshalling](../../../common/unmarshalling.md))
: reject if the field is missing or can't be unmarshalled to the given type

`"amount".as(unmarshaller)`
: extract the value of field "amount" with an explicit @apidoc[Unmarshaller]
: reject if the field is missing or can't be unmarshalled to the given type

`"distance".repeated`
: extract multiple occurrences of field "distance" as `Iterable[String]`

`"distance".as[Int].repeated`
: extract multiple occurrences of field "distance" as `Iterable[Int]`, you need a matching implicit @apidoc[Unmarshaller] in scope for that to work
(see also @ref[Unmarshalling](../../../common/unmarshalling.md))

`"distance".as(unmarshaller).repeated`
: extract multiple occurrences of field "distance" with an explicit @apidoc[Unmarshaller]


You can use @ref[Case Class Extraction](../../case-class-extraction.md) to group several extracted values together into a case-class
instance.

Requests missing a required field or field value will be rejected with an appropriate rejection.

There's also a singular version, @ref[formField](formField.md).

Query parameters can be handled in a similar way, see @ref[parameters](../parameter-directives/parameters.md).

## Unmarshalling

Data POSTed from [HTML forms](https://www.w3.org/TR/html401/interact/forms.html#h-17.13.4) is either of type `application/x-www-form-urlencoded` or of type
`multipart/form-data`. The value of an url-encoded field is a `String` while the value of a
`multipart/form-data`-encoded field is a "body part" containing an entity. This means that different kind of unmarshallers are needed depending
on what the Content-Type of the request is:

>
 * A `application/x-www-form-urlencoded` encoded field needs an implicit @apidoc[Unmarshaller[Option[String], T]]
 * A `multipart/form-data` encoded field needs an implicit `FromStrictFormFieldUnmarshaller[T]`

For common data-types, these implicits are predefined so that you usually don't need to care. For custom data-types it
should usually suffice to create a `FromStringUnmarshaller[T]` if the value will be encoded as a `String`.
This should be valid for all values generated by HTML forms apart from file uploads.

### Details

It should only be necessary to read and understand this paragraph if you have very special needs and need to process
arbitrary forms, especially ones not generated by HTML forms.

The `formFields` directive contains this logic to find and decide how to deserialize a POSTed form field:

>
 * It tries to find implicits of both types at the definition site if possible or otherwise at least one of both. If
none is available compilation will fail with an "implicit not found" error.
 * Depending on the `Content-Type` of the incoming request it first tries the matching (see above) one if available.
 * If only a @apidoc[Unmarshaller[Option[String], T]] is available when a request of type `multipart/form-data` is
received, this unmarshaller will be tried to deserialize the body part for a field if the entity is of type
`text/plain` or unspecified.
 * If only a `FromStrictFormFieldUnmarshaller[T]` is available when a request of type
`application/x-www-form-urlencoded` is received, this unmarshaller will be tried to deserialize the field value by
packing the field value into a body part with an entity of type `text/plain`. Deserializing will only succeed if
the unmarshaller accepts entities of type `text/plain`.

If you need to handle encoded fields of a `multipart/form-data`-encoded request for a custom type, you therefore need
to provide a `FromStrictFormFieldUnmarshaller[T]`.

## Example

@@snip [FormFieldDirectivesExamplesSpec.scala](/docs/src/test/scala/docs/http/scaladsl/server/directives/FormFieldDirectivesExamplesSpec.scala) { #formFields }

For more examples about the way how fields can specified see the examples for the @ref[parameters](../parameter-directives/parameters.md) directive.

@@@
