Basic Usage
Creating a .proto
File
In the resources/proto/examples
directory, the Clojure protobuf project provides an example “person” protobuf:
package protobuf.examples.person;
option java_outer_classname = "Example";
message Person {
required int32 id = 1;
required string name = 2;
optional string email = 3;
repeated string likes = 4;
}
Compiling .proto
to .java
and then to .class
A convenience script is provided to compile this: bin/compile-example-protobufs
. This will create a .java
file which will be saved in target/examples
.
The :test
profile in the project.clj
file has added target/examples
as one of its :java-source-paths
– as such, lein will compile the .java
files in target/examples
to .class
so that they can be called from Clojure.
If you started the project REPL with the command lein repl
, then all of this has already been done for you.
Using the Clojure API
From the dev REPL, pull in the core API and the compiled protobuf code:
[protobuf.dev] λ=> (require '[protobuf.core :as protobuf])
nil
[protobuf.dev] λ=> (import '(protobuf.examples.person Example$Person))
protobuf.examples.person.Example$Person
Now we can create a protobuf:
[protobuf.dev] λ=> (def p (protobuf/create
Example$Person
{:id 108
:name "Alice"
:email "alice@example.com"}))
#'protobuf.dev/p
[protobuf.dev] λ=> p
{:id 108, :name "Alice", :email "alice@example.com"}
The protocol buffer instance supports the usual Clojure operations:
[protobuf.dev] λ=> (assoc p :name "Alice B. Carol")
{:id 108, :name "Alice B. Carol", :email "alice@example.com"}
[protobuf.dev] λ=> (assoc p :likes ["climbing" "running" "jumping"])
{:id 108,
:name "Alice",
:email "alice@example.com",
:likes ["climbing" "running" "jumping"]}
Additionally, converting between protobuf bytes and Clojure data is trivial:
[protobuf.dev] λ=> (def b (protobuf/->bytes p))
#'protobuf.dev/b
[protobuf.dev] λ=> b
#object["[B" 0x7e3a40eb "[B@7e3a40eb"]
[protobuf.dev] λ=> (protobuf/bytes-> p b)
{:id 108, :name "Alice", :email "alice@example.com"}
Streams and Bytes
In addition to creating a protobuf instance from a Clojure map, Clojure protobuf also supports passing the following to the create
function:
- A Java byte array (i.e., of type
[B
) - A
java.io.InputStream
- A
com.google.protobuf.CodedInputStream
Just as with the creating one with a map, a protobuf class is expected as the first parameter.