This folder attempts to model book reviews as protocol buffers.
Install protoc
using the installation instructions.
mkdir ruby
protoc --ruby_out ruby book_reviews.proto
Install the google-protobuf
library:
gem install google-protobuf
You can then use it with:
require 'securerandom'
require './ruby/book_reviews_pb'
# Create a book with two titles
book = BookReviews::Book.new(
id: SecureRandom.uuid,
name: :The_Hobbit,
authors: [ 'J.R.R. Tolkien' ],
years: [ '1937' ],
publisher: 'Allen & Unwin',
titles: [
BookReviews::Book::Title.new(title: 'The Hobbit', link: 'https://en.wikipedia.org/wiki/The_Hobbit'),
BookReviews::Book::Title.new(title: 'Bilbo, le hobbit'),
]
)
File.write 'book.data', BookReviews::Book.encode(book)
# Create a user
user = BookReviews::User.new name: 'Jean Tessier', email: '[email protected]', password: 'abcd1234', roles: [ :ROLE_USER, :ROLE_ADMIN ]
user.id = SecureRandom.uuid
encoded_user = BookReviews::User.encode user
File.write 'user.data', encoded_user
# Create a review
review = BookReviews::Review.new reviewer: user, book: book, body: 'Awesome!'
review.id = SecureRandom.uuid
start = Date.parse('2022-06-04')
review.start = Google::Protobuf::Timestamp.new seconds: start.to_time.to_i, nanos: start.to_time.nsec
File.write 'review.data', BookReviews::Review.encode(review)
# Technically, nanos on dates are always 0, so we can rewrite the start as:
# review.start = Google::Protobuf::Timestamp.new seconds: Date.parse('2022-06-04').to_time.to_i
# Read a user from a protobuf
decoded_user = BookReviews::User.decode encoded_user
Ruby supports binary and JSON protobufs.
File I/O with a serialized protobuf:
require './ruby/book_reviews_pb'
# Write the user to a binary protobuf in a file
File.write 'user.data', BookReviews::User.encode(user)
# Read a user from a binary protobuf
user = nil
File.open 'user.data' do |f|
user = BookReviews::User.decode f.read
end
File I/O with a JSON protobuf:
require './ruby/book_reviews_pb'
# Write the user to a binary protobuf in a file
File.write 'user.json', BookReviews::User.encode_json(user)
# Read a user from a binary protobuf
user = nil
File.open 'user.json' do |f|
user = BookReviews::User.decode_json f.read
end
protoc --decode book_reviews.Book book_reviews.proto < book.data
protoc --decode book_reviews.User book_reviews.proto < user.data
protoc --decode_raw < book.data
protoc --decode_raw < user.data
mkdir java
protoc --java_out java book_reviews.proto
You will need JAR files for:
com.google.protobuf:protobuf-java
com.google.protobuf:protobuf-java-util
com.google.code.gson:gson
Copy them to java/lib
.
Add them to your CLASSPATH
for convenience.
for f in java/lib/* java/classes
do
export CLASSPATH=$f:$CLASSPATH
done
To compile the protobuf classes:
mkdir java/classes
javac -d java/classes java/book_reviews/BookReviews.java
To create entities in Java:
import com.google.protobuf.Timestamp;
import book_reviews.BookReviews;
# Create a book with two titles
BookReviews.Book book = BookReviews.Book
.newBuilder()
.setId(UUID.randomUUID() as String)
.setName("The_Hobbit")
.addAuthors("J.R.R. Tolkien")
.addYears("1937")
.setPublisher("Allen & Unwin")
.addTitles(
BookReviews.Book.Title
.newBuilder()
.setTitle("The Hobbit")
.setLink("https://en.wikipedia.org/wiki/The_Hobbit")
)
.addTitles(
BookReviews.Book.Title
.newBuilder()
.setTitle("Bilbo, le hobbit")
)
.build();
# Create a user
BookReviews.User user = BookReviews.User
.newBuilder()
.setId(UUID.randomUUID() as String)
.setName("Jean Tessier")
.setEmail("[email protected]")
.setPassword("abcd1234")
.addRoles("ROLE_USER")
.addRoles("ROLE_ADMIN")
.build();
# Create a review
BookReviews.Review review = BookReviews.Review
.newBuilder()
.setId(UUID.randomUUID() as String)
.setReviewer(user)
.setBook(book)
.setBody("Awesome!")
.setStart(Timestamp.fromMillis(System.currentTimeMillis()))
.build();
To create entities in Groovy:
import com.google.protobuf.util.Timestamps
import book_reviews.BookReviews
# Create a book with two titles
book_builder = BookReviews.Book.newBuilder()
book_builder.id = UUID.randomUUID() as String
book_builder.name = "The_Hobbit"
book_builder.addAuthors "J.R.R. Tolkien"
book_builder.addYears "1937"
book_builder.publisher = "Allen & Unwin"
title_builder = BookReviews.Book.Title.newBuilder()
title_builder.title = "The Hobbit"
title_builder.link = "https://en.wikipedia.org/wiki/The_Hobbit"
book_builder.addTitles(title_builder)
title_builder.title = "Bilbo, le hobbit"
title_builder.clearLink()
book_builder.addTitles(title_builder)
book = book_builder.build()
# Create a user
user_builder = BookReviews.User.newBuilder()
user_builder.id = UUID.randomUUID() as String
user_builder.name = "Jean Tessier"
user_builder.email = "[email protected]"
user_builder.password = "abcd1234"
user_builder.addRoles "ROLE_USER"
user_builder.addRoles "ROLE_ADMIN"
user = user_builder.build()
# Create a review
review_builder = BookReviews.Review.newBuilder()
review_builder.id = UUID.randomUUID() as String
review_builder.reviewer = user
review_builder.book = book
review_builder.body = "Awesome!"
review_builder.start = Timestamps.fromMillis System.currentTimeMillis()
review = review_builder.build();
Java supports binary, JSON, and text protobufs.
File I/O with a serialized protobuf:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import book_reviews.BookReviews;
# Write the user to a binary protobuf in a file
try (FileOutputStream output = new FileOutputStream("user.data")) {
user.writeTo(output);
}
# Read a user from a binary protobuf
BookReviews.User user = BookReviews.User.parseFrom(new FileInputStream("user.data"));
File I/O with a JSON protobuf:
import java.io.FileReader;
import java.io.FileWriter;
import com.google.protobuf.util.JsonFormat;
import book_reviews.BookReviews;
# Write the user to a JSON protobuf in a file
JsonFormat.Printer printer = JsonFormat.printer();
try (FileWriter writer = new FileWriter("user.json")) {
writer.print(printer.print(user));
}
# Read a user from a JSON protobuf
JsonFormat.Parser parser = JsonFormat.parser();
BookReviews.User.Builder builder = BookReviews.User.newBuilder();
try (FileReader reader = new FileReader("user.json")) {
parser.merge(reader, builder);
}
BookReviews.User user = builder.build();
File I/O with a text protobuf:
import java.io.FileReader;
import java.io.FileWriter;
import com.google.protobuf.TextFormat;
import book_reviews.BookReviews;
# Write the user to a text protobuf in a file
TextFormat.Printer printer = TextFormat.printer();
try (FileWriter writer = new FileWriter("user.text")) {
printer.print(user, writer);
}
# Read a user from a JSON protobuf
TextFormat.Parser parser = Text Format.parser();
BookReviews.User.Builder builder = BookReviews.User.newBuilder();
try (FileReader reader = new FileReader("user.text")) {
parser.merge(reader, builder);
}
BookReviews.User user = builder.build();
mkdir python
protoc --python_out python book_reviews.proto
Install the protobuf
library:
pip3 install protobuf
Create a user:
import uuid
import python.book_reviews_pb2 as book_reviews
# Create a user
user = book_reviews.User()
user.id = str(uuid.uuid4())
user.name = "Jean Tessier"
user.email = "[email protected]"
user.password = "abcd1234"
user.roles.append("ROLE_USER")
user.roles.append("ROLE_ADMIN")
Python supports binary and text protobufs.
File I/O with a serialized protobuf:
import python.book_reviews_pb2 as book_reviews
# Write the user to a binary protobuf in a file
with open("user.data", "wb") as f:
f.write(user.SerializeToString())
# Read a user from a binary protobuf
decoded_user = book_reviews.User()
with open("user.data", "rb") as f:
decoded_user.ParseFromString(f.read())
File I/O with a text protobuf:
from google.protobuf import text_format
import python.book_reviews_pb2 as book_reviews
# Write the user to a text protobuf in a file
with open("user.txt", "w") as f:
f.write(text_format.MessageToString(user))
# Read a user from a text protobuf
read_user = book_reviews.User()
with open("user.txt") as f:
text_format.Parse(f.read(), read_user)