Skip to content
Santekno.com | Tech Tutorials and Trends
EN
📖 0%
23 Jul 2025 · 5 min read ·Article 45 / 110
Go

45 How to Use `option` in Protobuf

IH
Ihsan Arif
Writer at Santekno · Backend Engineer

One of the powerful features of Protocol Buffers (Protobuf) that many engineers often overlook is the use of option. Understanding and making the most of options in Protobuf can be tremendously helpful when designing API contracts that are more flexible and maintainable. In this article, I’ll cover thoroughly what option is, how to use it, examples of applying it at various levels, and even how to write your own custom options, complete with code examples, real-world case simulations, reference tables, and flow diagrams.


Getting to Know option in Protobuf

Before we dive into code examples, let’s briefly discuss what option actually is.

option in Protobuf is a metadata feature that can be attached to various entities such as files, messages, fields, enums, and services. Its purpose is to provide special instructions to the code generator (for example, protoc) or other tools that read the Protobuf schema.

Some of the options we frequently encounter include:

  • java_package
  • deprecated
  • json_name
  • default
Danger
🎯 In short: options serve as additional instructions in the .proto file without directly affecting the message contents, but they can change the behavior embedded in language-specific code, documentation, or related tools.

Placement and Scope of Options

Options can be placed at various levels. Let’s look at the following table for a summary:

ScopeExample OptionExample Syntax in .proto
Filejava_packageoption java_package = "com.blog";
Messagemessage_set_wire_formatoption (xyz.my_opt) = true;
Fielddeprecated, json_namestring username = 1 [deprecated=true];
Enum/EnumValallow_aliasoption allow_alias = true;
Service-option deprecated = true;
Custom[custom options]option (my_custom) = "value";


Examples of Built-in Options

Let’s get into real code. We’ll use a .proto file to demonstrate some of the most useful built-in options.

protobuf
 1syntax = "proto3";
 2
 3option java_package = "com.medium.protobuf";
 4option go_package = "github.com/username/project/proto";
 5
 6message User {
 7    string name = 1;
 8    int32 age = 2 [deprecated = true];
 9    string email = 3 [json_name = "userEmail"];
10}
11
12enum Status {
13    option allow_alias = true;
14    UNKNOWN = 0;
15    ACTIVE = 1;
16    ENABLED = 1;
17}

Code explanation:

  • java_package & go_package set the namespace of the code generator output in Java/Go.
  • The field option on age marks that field as deprecated, both in the documentation and in the runtime code.
  • json_name affects the result of serialization to JSON.
  • On the enum, the option allow_alias = true allows two enum values (ACTIVE, ENABLED) to share the same number.

Automatically Generated Code Output

For example, on the deprecated age field, the generated output in Go (the comment in the struct) will look like this:

go
1// Deprecated: Do not use.
2Age int32 `protobuf:"varint,2,opt,name=age,proto3" json:"age,omitempty"`

This helps other teams know that this property should be avoided.


Custom Options: More Than Just Metadata

A truly powerful feature is the ability to define your own options, so that code generator plugins or linters can read unique instructions of your own making.

1. Define a Custom option

Custom options are defined via a proto extension of the google.protobuf standard options.

protobuf
1// custom_options.proto
2syntax = "proto3";
3
4import "google/protobuf/descriptor.proto";
5
6extend google.protobuf.FieldOptions {
7  string sensitive = 50001;
8}
Danger
Note: Use a large ID (field number) so it doesn’t clash with existing ones.

2. Using It in a Protobuf Schema

protobuf
1// user.proto
2syntax = "proto3";
3
4import "custom_options.proto";
5
6message User {
7    string password = 1 [(sensitive) = "Yes"];
8    string email    = 2;
9}

With this, a custom generator plugin can read whether a field contains a sensitive value (for example: a password), so that the logging layer can automatically mask it.


Simulating the Option Workflow (Mermaid)

Let’s imagine the workflow of how options are processed by the Protobuf toolset.

MERMAID
flowchart LR
    subgraph Dev
      A[Write .proto file] -->|Add option| B
    end
    B[Protoc Compiler] --> C{Baca option}
    C -->|Standard option| D[Protoc generated code]
    C -->|Custom option| E[Plugin / Linter]
    E --> F[Custom Behavior]

Explanation:

  1. The engineer writes the .proto and fills in options at various scopes.
  2. The protoc compiler reads the options.
  3. For standard options, the official code generator applies the behavior.
  4. For custom options, a plugin or external tool can perform extra automation—for example masking, validation, generating additional documentation, and so on.

Case Study: Automatic Logging Masking

It often happens that sensitive fields such as passwords or tokens are not masked when logging requests in a backend service. With a custom option, we can automate this masking!

1. Tagging in the .proto

protobuf
1message LoginRequest {
2    string username = 1;
3    string password = 2 [(sensitive) = "true"];
4}

2. Implementation in Code Generation/Plugin

Your Go/Node.js plugin can read this metadata:

go
1if field.Options.Sensitive == "true" {
2    // When logging the request, mask this field as "*****"
3}

The result:

bash
1Received: {"username":"devuser","password":"*****"}


Summary Table of Option Examples

OptionLevelPurpose
java_packageFileNamespace of generated code in Java
go_packageFileNamespace of generated code in Go
deprecatedFieldMarks a field/class as no longer recommended for use
json_nameFieldAlternative name during JSON serialization
allow_aliasEnumAllow duplicate enum numbers
**(sensitive) (custom)FieldCustom metadata, e.g. masking instructions in logging

When Should You Use Options?

  • When the API spans multiple teams/programming languages
  • When you want to enforce custom rules (custom linters, doc generators)
  • When you need richer API contract documentation
  • To automate behaviors such as default values, masking, deprecation

Conclusion

Using option in Protobuf is one of the highly beneficial techniques in managing data schemas & modern API communication. Standard options help with cross-language portability, while custom options open up opportunities for automation and enforcing semantic policy on enterprise APIs.

Danger
From simple things like deprecating a field all the way to masking sensitive data, everything can be arranged through options. Your code and API contracts become far more powerful!

Don’t hesitate to experiment with custom options & Protobuf plugins. By understanding how options work, you can create APIs that are maintainable, future-proof, and trusted by the entire team ❤️

🚀 Want to discuss implementing custom options in your stack? Write your questions in the comments!

Related Articles

💬 Comments