protoless

Travis GitHub tag Gitter

EXPERIMENTAL PROJECT, NOT MAINTENED ANYMORE. DO NOT USE IT IN PRODUCTION, OR AT YOUR OWN RISK!.

protoless is a Protobuf 3 serialization library in Scala for JVM, based on automatic type class derivation to perfectly fit your models.

The type class derivation approach allows to generate type-safe Encoders and Decoders at compile-time for your own models, without code-generation. The derivation is done with Shapeless, No macro were harmed in the making of this library.

Schema-free doesn't imply any loss of consistency. If you have one, you can still validate it at compile-time with yours models (not implemented yet).

protoless is heavily inspired by awesome work made on Circe by Travis Brown, so the design of their public APIs has a lot in common.

QuickStart

protoless is published to bintray.com/julien-lafont and cross-built for scala 2.11.8, and scala 2.12.3, so you can just add the following to your build:

resolvers += Resolver.bintrayRepo("julien-lafont", "maven")

libraryDependencies ++= Seq(
  "io.protoless" %% "protoless-core" % "0.0.7",
  "io.protoless" %% "protoless-generic" % "0.0.7"
)

Type sbt console to start a REPL and then paste the following the following code:

import io.protoless._, io.protoless.messages._, io.protoless.generic.auto._

case class Person(firstname: String, lastname: String, age: Option[Int], locations: Seq[String])

val p = Person("John", "Doe", Some(28), Seq("Paris", "London", "New York"))
// p: Person = Right(Person(John, Doe, Some(28), Seq(Paris, London, New York)

val byte = Encoder[Person].encode(p) // or p.asProtobufBytes
// bytes: Array[Byte] = Array(10, 4, 74, 111, 104, 110, 18, ...)

Decoder[Person].decode(bytes) // or bytes.as[Person]
// res1: Either[DecodingFailure, Person] = Right(Person(John, Doe, Some(28), Seq(Paris, London, New York)))

No boilerplate, no runtime reflection.

Documentation

The full documentation is available here: https://julien-lafont.github.io/protoless.

Why?

ScalaPB, a protocol buffers compiler for scala, was the only serious library to work with protobuf in Scala, but it comes with:

  • Two step code generation (protobuf -> java, java -> scala)
    • And if you want to map your own model, you need a third wrapping level.
  • Heavy builder interface
  • Custom lenses library

protoless proposes a different approach, your lightweight models drive the protobuf serialization, without weighing it down.

State of progress

  • Encoding/decoding protobuf native fields.
  • Encoding/decoding scala native types (collections, bigdecimal, enum, etc).
  • Work with optional and repeated fields.
  • Support signed/unsigned/fixed int32/64 with tagging.
  • Automatic encoder/decoder for basic protobuf messages (fields numbered consecutively starting from one).
  • Semi-automatic encoder/decoder for message with fields not numbered consecutively.
  • Auto-derivation of value class.
  • Support nested message.
  • Fluid syntax to write custom message decoder/encoder
  • Support default value #3
  • Compile time schema validation. #4
  • And last, but not least, GRPC integration.

Contributing

The protoless project welcomes contributions from anybody wishing to participate. All code or documentation that is provided must be licensed with the same license that Protoless is licensed with (Apache 2.0, see LICENSE file).

Feel free to open an issue if you notice a bug, have an idea for a feature, or have a question about the code. Pull requests are also gladly accepted. You can also just enter in the gitter channel to talk with us.

License

Code is provided under the Apache 2.0 license available at http://opensource.org/licenses/Apache-2.0, as well as in the LICENSE file.