Skip to content

Instantly share code, notes, and snippets.

@vi-kas
Created October 5, 2019 04:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vi-kas/8c9fa93e5eb62ffebe837b2b07dd53af to your computer and use it in GitHub Desktop.
Save vi-kas/8c9fa93e5eb62ffebe837b2b07dd53af to your computer and use it in GitHub Desktop.
Circe Json Marshaller for akka-http
import akka.http.scaladsl.marshalling.{Marshaller, ToEntityMarshaller}
import akka.http.scaladsl.model.MediaTypes.`application/json`
import akka.http.scaladsl.model.{ContentType, ContentTypeRange, HttpEntity, MediaType}
import akka.http.scaladsl.unmarshalling.{FromEntityUnmarshaller, Unmarshaller}
import akka.util.ByteString
import io.circe._
/**
* https://doc.akka.io/docs/akka-http/current/common/marshalling.html
=== Dependencies ===
"com.typesafe.akka" %% "akka-http" % "10.1.10",
"com.typesafe.akka" %% "akka-stream" % "2.5.23",
"io.circe" %% "circe-core" % "0.11.1",
"io.circe" %% "circe-generic" % "0.11.1",
"io.circe" %% "circe-parser" % "0.11.1"
*/
trait CirceMarshallable {
def unmarshallerContentTypes: Seq[ContentTypeRange] =
mediaTypes.map(ContentTypeRange.apply)
def mediaTypes: Seq[MediaType.WithFixedCharset] = List(`application/json`)
implicit def jsonMarshaller(implicit printer: Printer): ToEntityMarshaller[Json] =
Marshaller.oneOf(mediaTypes: _*){mediaType =>
Marshaller.withFixedContentType(ContentType(mediaType)){json =>
HttpEntity(mediaType,
ByteString(printer.prettyByteBuffer(json, mediaType.charset.nioCharset())))
}
}
implicit def marshaller[A: Encoder](implicit printer: Printer = Printer.noSpaces): ToEntityMarshaller[A] =
jsonMarshaller(printer).compose(Encoder[A].apply)
implicit final val jsonUnmarshaller: FromEntityUnmarshaller[Json] =
Unmarshaller.byteStringUnmarshaller
.forContentTypes(unmarshallerContentTypes: _*)
.map {
case ByteString.empty => throw Unmarshaller.NoContentException
case data => jawn.parseByteBuffer(data.asByteBuffer).fold(throw _, identity)
}
implicit final def unmarshaller[A: Decoder]: FromEntityUnmarshaller[A] = {
def decode(json: Json): A = Decoder[A].decodeJson(json).fold(throw _, identity)
jsonUnmarshaller.map(decode)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment