Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Can I Return Protocol Buffers Directly in Play! 2.0 Framework?

Play lets you return a number of different types directly in your controllers, such as JsValue or XML along with plain text. I would like to extend this to accept protocol buffers, so I can write:

def page = Action {
    val protobuf = //...
    Ok(protobuf)
}
like image 421
Jacob Groundwater Avatar asked Aug 23 '12 06:08

Jacob Groundwater


People also ask

Is Protobuf backwards compatible?

Protocol buffers provide a language-neutral, platform-neutral, extensible mechanism for serializing structured data in a forward-compatible and backward-compatible way.

What is protocol buffer in gRPC?

Protocol buffers are Google's language-neutral, platform-neutral, extensible mechanism for serializing structured data – think XML, but smaller, faster, and simpler.

What is the difference between proto2 and Proto3?

Proto3 is the latest version of Protocol Buffers and includes the following changes from proto2: Field presence, also known as hasField , is removed by default for primitive fields. An unset primitive field has a language-defined default value.

What are Protocol buffers used for?

Protocol Buffers (Protobuf) is a free and open-source cross-platform data format used to serialize structured data. It is useful in developing programs to communicate with each other over a network or for storing data.


1 Answers

Protocol buffers in Java all inherit from a single com.google.protobuf.Message class.

Add the following implicit conversions within the scope of your application controller:

implicit def contentTypeOf_Protobuf: ContentTypeOf[Message] = {
  ContentTypeOf[Message](Some("application/x-protobuf"))
}
implicit def writeableOf_Protobuf: Writeable[Message] = {
  Writeable[Message](message => message.toByteArray())
}

These will allow Play to serialize buffers directly in a response given by a status such as Ok(protobuf)

Update:

I have posted a working example of the reverse situation, where the incoming request can be parsed and a protobuf can be extracted automatically.

  • https://gist.github.com/3455432

The parser takes the form of an action in this example, tho you could also code a body parser:

object Put extends Controller {
  def index = DecodeProtobuf(classOf[MyProtobuf]) { stack :MyProtobuf =>
    Action {
      // do something with stack
    }
  }
}

The client sending the request should serialize the buffer as a byte array, and pass it directly in the body of the request.

like image 65
Jacob Groundwater Avatar answered Oct 19 '22 03:10

Jacob Groundwater