protoc-gen-go-json
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.
Install
go install github.com/mfridman/protoc-gen-go-json@latest
protoc-gen-go-json --version
Also required:
Usage
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:
Using protoc
protoc --go_out=. --go-json_out=. request.proto
Using buf
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=true
And then run:
buf generate request.proto
Your 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
:
Opaque API (added in google.golang.org/protobuf v1.36.0
)
// 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"}
Open API (access to the underlying fields)
// 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())
// alice
From the root of this repository, you can run the following to see the example in action:
go run ./examples
Options
The 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.
Marshal Options
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 |
Unmarshal Options
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 path
paths=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=true
Acknowledgements
This 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.