This is a Protobuf plugin for Go that generates code to implement json.Marshaler and json.Unmarshaler using protojson.
This enables Go-generated protobuf messages to be embedded directly within other structs and encoded
with the standard JSON library, since the standard encoding/json library can't encode certain
protobuf messages such as those that contain oneof fields.
Tip
For list of chanegs between versions, see the CHANGELOG.md.
go install github.com/mfridman/protoc-gen-go-json@latest
protoc-gen-go-json --version
Also required:
Define your messages like normal:
syntax = "proto3";
package api.v1;
message Request {
oneof kind {
string name = 1;
int32 code = 2;
}
}The example message purposely uses a oneof since this won't work by default with encoding/json.
Next, generate the code:
protoc --go_out=. --go-json_out=. request.proto
version: v2
plugins:
- remote: buf.build/protocolbuffers/go
out: gen/go
opt: paths=source_relative
- remote: buf.build/community/mfridman-go-json
out: gen/go
opt:
- paths=source_relative
- orig_name=trueAnd then run:
buf generate request.protoYour output should contain a file request.pb.json.go which contains the implementation of
json.Marshal/Unmarshal for all your message types. You can then encode your messages using
standard encoding/json:
// Marshal
//
// Use a builder
req := apiv1.Request_builder{
Name: proto.String("alice"),
}.Build()
// Or, use the setter
req := &apiv1.Request{}
req.SetName("alice")
by, err := json.Marshal(req)
fmt.Println(string(by))
// {"name":"alice"}// Marshal
by, err := json.Marshal(&apiv1.Request{
Kind: &apiv1.Request_Name{
Name: "alice",
},
})
fmt.Println(string(by))
// {"name":"alice"}
// Unmarshal
var request apiv1.Request
err := json.Unmarshal(by, &request)
fmt.Println(request.GetName())
// aliceFrom the root of this repository, you can run the following to see the example in action:
go run ./examplesThe generator supports options to control the behavior of the generated code. The options are passed
as a comma-separated list to the --go-json_out flag.
See the protojson.MarshalOptions for documentation on these options.
| Option | Description | Default |
|---|---|---|
enums_as_ints |
Render enums as integers instead of strings | false |
emit_defaults |
Render fields with zero values | false |
emit_defaults_without_null |
Render fields with zero values without null values | false |
orig_name |
Use original (.proto file) name for fields | false |
See the protojson.UnmarshalOptions for documentation on these options.
| Option | Description | Default |
|---|---|---|
allow_unknown |
Disallow unknown fields when unmarshaling | false |
It also includes the "standard" options available to all protogen-based plugins:
import_path={path}- Override the import pathpaths=source_relative- Derive the output path from the input path- etc.
These can be set as part of the --go-json_out value:
protoc --go-json_opt=emit_defaults=true:.You can specify multiple using a ,:
protoc --go-json_out=enums_as_ints=true,emit_defaults=true:.Alternatively, you may also specify options using the --go-json_opt value:
protoc --go-json_out:. --go-json_opt=emit_defaults=true,enums_as_ints=trueThis project is a clone of mitchellh/protoc-gen-go-json. The original project is no longer maintained and this project is a continuation of it. To learn more see Mitchell's Planned Repo Archive gist for more information.