Git Product home page Git Product logo

circe-empty-aware's Introduction

circe-empty-aware

This provide a way to make circe (https://github.com/circe/circe) encoders empty aware.

To use add to your build.sbt:

lazy val emptyAwareProject = RootProject( uri("git://github.com/opbokel/circe-empty-aware#v0.5") ) and add this on your root project definition .dependsOn(emptyAwareProject)

The problem:

If you have several objects with lots of optional fields and/or empty arrays. Let's see the example below:

case class Documentation(userInstruction: Option[String] = None, quickTips: Option[String] = None)

Documentation is a class with two optional fields

case class ItemOptDoc(name: String, documentation: Option[Documentation])

An ItemOptDoc have a name and possibly a Documentation. This was made that way to allow the encoded json to support null documentation key and reduce payload.

And the encoders are something like this:

implicit val docEncoder = deriveEncoder[Documentation]

implicit val itemOptEncoder = deriveEncoder[ItemOptDoc]

But this means that now I have one extra complexity and two ways to represent a empty Documentation object in scala. It makes the code more complex because of the JSON encoding.

/**
* Bouth represent empty Documentation
**/
ItemOptDoc("item 1", None)

ItemOptDoc("item 2", Some(Documentation()))

So, the simpler (and probably best) way the make it in Scala is to declare item like this, without an optional field...

case class Item(name: String, documentation: Documentation)

and solve the problem on the encoder. But writing custom encoders for each object is a boring process...

If we don't define a custom encoder we will produce a result like bellow. If you have a lot objects like item 1, it will increase your payload, memory consumption and JSON readability:

implicit val itemEncoder = deriveEncoder[Item]

itemEncoder(Item("Item 1", Documentation()))

itemEncoder(Item("Item 2", Documentation(Some("User instructions..."),Some("Good tips"))))

Produced JSONs:

{
  "name" : "Item 1",
  "documentation" : {
    "userInstruction" : null,
    "quickTips" : null
  }
}

{
  "name" : "Item 2",
  "documentation" : {
    "userInstruction" : "User instructions...",
    "quickTips" : "Good tips"
  }
}

Solution:

Let the Encoder represent the Documentation Object as null if the Json generated by the Documentation encoder is empty.

A Value is considered empty if it is a empty array, null, a empty object or if all the keys on the object are associated with empty values.

Lets replace the Documentation encoder with a empty aware encoder:

import com.opb.circe.EmptyAwareEncoder._

implicit val docEncoder = deriveEncoder[Documentation].asEmptyAware()

itemEncoder(Item("Item 1", Documentation()))

itemEncoder(Item("Item 2", Documentation(Some("User instructions..."),Some("Good tips"))))

The produced result:

//Item 1 documentation have been replaced by null 
{
  "name" : "Item 1",
  "documentation" : null
}

//Item 2 still the same
{
  "name" : "Item 2",
  "documentation" : {
    "userInstruction" : "User instructions...",
    "quickTips" : "Good tips"
  }
}

Using it in conjunction with the io.circe.Printer option of dropNullValues = true we have the final output to the item 1 bellow:

{
  "name" : "Item 1"
}

Making a huge difference on a possible endpoint that returns thousands of items, reducing payload an saving memory.

Please see the Scaladoc on EmptyAwareEncoder to see all the usage possibilities

circe-empty-aware's People

Contributors

opbokel avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.