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"}