Entities
In HTTP, the term "entity" refers to the body of a request. For example, a JSON request will have JSON data in the entity. An Entity in Krop is responsible for converting an HTTP entity into a Scala type, and converting a Scala type into an HTTP entity. Entity is therefore a type of codec.
As well an decoding and encoding data, an Entity also specifies the Content-Type is supports for decoding and encoding. It is usually the case that the decoding Content-Type is more permissive than the encoding Content-Type. For example Entity.text
will decode text/*
but encodes text/plain
.
The Entity type is defined as Entity[D, E]
, where D
is the type of value that will be decoded from an HTTP request, and E
is the type of values that will be encoded in a response. Most of the time D
and E
are the same, and the entity is called an InvariantEntity. Occassionally, however, they differ. For example, the ScalaTags entity decodes a String
but encodes ScalaTags' data structure. This is because there is no parser from String
to ScalaTags, so there is no way to parse an HTTP request with an HTML entity into ScalaTags.
Simple Entities
Simple entities decode and encode Scala types without an intermediaries. You should check the Entity companion object for the full list of supported entities, but here are some of the most commonly used:
Entity.json
is an InvariantEntity for Circe'sJSON
type, decoding and encoding Content-Typeapplication/json
.Entity.html
is an InvariantEntity forString
, decoding and encoding Content-Typetext/html
.Entity.scalatags
is an Entity decodingString
and encoding Scalatag'sTypedTag[String]
type, with Content-Typetext/html
.Entity.text
is an InvariantEntity forString
, decoding Content-Typetext/*
and encoding Content-Typetext/plain
.Entity.twirl
is an Entity decodingString
and encoding Twirl'sHtml
type, with Content-Typetext/html
.
JSON
Krop, by default, uses Circe for JSON decoding and encoding. If you have a type A
that you want to decode and encode as JSON, assuming you have created given instances of Circe's Decoder
and Encoder
type for A
, creating an InvariantEntity is as simple as calling
Entity.jsonOf[A]
.
Here's a quick example, using Circe's semi-automatic generic derivation to create the Decoder
and Encoder
types.
import io.circe.{Decoder, Encoder}
import krop.all.*
final case class Cat(name: String) derives Decoder, Encoder
val jsonEntity = Entity.jsonOf[Cat]
Forms
Decoding and encoding of form data delegates to a FormCodec given instance. The usual way to create such an instance if with generic derivation. Here is an example, showing both generic derivation of the FormCodec
instance and creation of an Entity using Entity.formOf
.
final case class Dog(name: String) derives FormCodec
val formEntity = Entity.formOf[Dog]