/protoc-gen-go-json

Protobuf plugin to generate Go JSON Marshal/Unmarshal methods for messages using protojson

Primary LanguageGoMIT LicenseMIT

protoc-gen-go-json

Build Report Card Go Reference

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

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: v1
plugins:
  - name: buf.build/protocolbuffers/go
    out: gen/go
    opt: paths=source_relative
  - name: 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:

import "encoding/json"

// Marshal
bs, err := json.Marshal(&Request{
  Kind: &Kind_Name{
    Name: "alice",
  },
}

// Unmarshal
var result Request
json.Unmarshal(bs, &result)

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.