aboutsummaryrefslogtreecommitdiffhomepage
path: root/ruby/README.md
blob: 62a6486368c54f3d78e5e452ff4df8c054d3db1f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
This directory contains the Ruby extension that implements Protocol Buffers
functionality in Ruby.

The Ruby extension makes use of generated Ruby code that defines message and
enum types in a Ruby DSL. You may write definitions in this DSL directly, but
we recommend using protoc's Ruby generation support with .proto files. The
build process in this directory only installs the extension; you need to
install protoc as well to have Ruby code generation functionality.

JSON Migration Note
-------------------

Users who were using the protobuf Gem `<= 3.0.0.alpha.5.0.4` will notice that
the JSON format has changed slightly and is incompatible with previous
versions.

The change concerns field names.  Prior to the change, field names from the
.proto file were used verbatim.  Take this `.proto` file:

```protobuf
syntax = "proto3";

message M {
  int32 my_int_field = 1;
  bool my_bool_field = 2;
}
```

Serializing to JSON used to give you something like this:

```json
{"my_int_field":1, "my_bool_field":true}
```

However this format was not compatible with the proto3 JSON spec.  To be
compliant with proto3 JSON, we need to camel-case the names:

```json
{"myIntField":1, "myBoolField":true}
```

Starting with `3.0.0.alpha.5.0.5`, this bug was fixed and we now produce the
correct camelCased names.  However this may cause compatibility problems for
JSON users who can't upgrade everything at the same time, or who store
serialized JSON payloads.  To mitigate this and allow time for migration, the
library currently recognizes two environment variables:

  - `UPB_JSON_ACCEPT_LEGACY_FIELD_NAMES`: set this variable to instruct the
    JSON parser that the old names should be accepted in addition to the new,
    compliant ones.  This will make the parser compatible with both formats.
  - `UPB_JSON_WRITE_LEGACY_FIELD_NAMES`: set this variable to instruct the
    JSON serializer to encode the old, non-compliant names.

These options will be removed in a future version of Ruby protobuf.  All
users shoud migrate to the standard names.

If users have existing payloads in the old format and cannot easily migrate,
the best solution would be to specify the old names explicitly in the
`.proto` file using the `json_name` option.  For example, for the .proto
file above, the user could specify:

```protobuf
syntax = "proto3";

message M {
  int32 my_int_field = 1 [json_name="my_int_field"];
  bool my_bool_field = 2 [json_name="my_bool_field"];
}
```

This will make all compliant proto3 JSON parsers/serializers use the
non-camel-cased names forever.  Note that protobuf Ruby does *not yet*
support this option properly, but support is forthcoming.  It will
certainly be supported before the environment variables above are
removed.


Installation from Gem
---------------------

When we release a version of Protocol Buffers, we will upload a Gem to
[RubyGems](https://www.rubygems.org/). To use this pre-packaged gem, simply
install it as you would any other gem:

    $ gem install [--prerelease] google-protobuf

The `--pre` flag is necessary if we have not yet made a non-alpha/beta release
of the Ruby extension; it allows `gem` to consider these "pre-release"
alpha/beta versions.

Once the gem is installed, you may or may not need `protoc`. If you write your
message type descriptions directly in the Ruby DSL, you do not need it.
However, if you wish to generate the Ruby DSL from a `.proto` file, you will
also want to install Protocol Buffers itself, as described in this repository's
main `README` file. The version of `protoc` included in the latest release
supports the `--ruby_out` option to generate Ruby code.

A simple example of using the Ruby extension follows. More extensive
documentation may be found in the RubyDoc comments (`call-seq` tags) in the
source, and we plan to release separate, more detailed, documentation at a
later date.

```ruby
require 'google/protobuf'

# generated from my_proto_types.proto with protoc:
#  $ protoc --ruby_out=. my_proto_types.proto
require 'my_proto_types'

mymessage = MyTestMessage.new(:field1 => 42, :field2 => ["a", "b", "c"])
mymessage.field1 = 43
mymessage.field2.push("d")
mymessage.field3 = SubMessage.new(:foo => 100)

encoded_data = MyTestMessage.encode(mymessage)
decoded = MyTestMessage.decode(encoded_data)
assert decoded == mymessage

puts "JSON:"
puts MyTestMessage.encode_json(mymessage)
```

Installation from Source (Building Gem)
---------------------------------------

To build this Ruby extension, you will need:

* Rake
* Bundler
* Ruby development headers
* a C compiler

To Build the JRuby extension, you will need:

* Maven
* The latest version of the protobuf java library (see ../java/README.md)
* Install JRuby via rbenv or RVM

First switch to the desired platform with rbenv or RVM.

Then install the required Ruby gems:

    $ gem install bundler
    $ bundle

Then build the Gem:

    $ rake
    $ rake clobber_package gem
    $ gem install `ls pkg/google-protobuf-*.gem`

To run the specs:

    $ rake test

This gem includes the upb parsing and serialization library as a single-file
amalgamation. It is up-to-date with upb git commit
`535bc2fe2f2b467f59347ffc9449e11e47791257`.

Version Number Scheme
---------------------

We are using a version number scheme that is a hybrid of Protocol Buffers'
overall version number and some Ruby-specific rules. Gem does not allow
re-uploads of a gem with the same version number, so we add a sequence number
("upload version") to the version. We also format alphabetical tags (alpha,
pre, ...) slightly differently, and we avoid hyphens. In more detail:

* First, we determine the prefix: a Protocol Buffers version "3.0.0-alpha-2"
  becomes "3.0.0.alpha.2". When we release 3.0.0, this prefix will be simply
  "3.0.0".
* We then append the upload version: "3.0.0.alpha.2.0" or "3.0.0.0". If we need
  to upload a new version of the gem to fix an issue, the version becomes
  "3.0.0.alpha.2.1" or "3.0.0.1".
* If we are working on a prerelease version, we append a prerelease tag:
  "3.0.0.alpha.3.0.pre". The prerelease tag comes at the end so that when
  version numbers are sorted, any prerelease builds are ordered between the
  prior version and current version.

These rules are designed to work with the sorting rules for
[Gem::Version](http://ruby-doc.org/stdlib-2.0/libdoc/rubygems/rdoc/Gem/Version.html):
release numbers should sort in actual release order.