Skip to content

Nested Types in Protocol Buffers

DodaTech Updated 2026-06-28 3 min read

In this tutorial, you will learn about Nested Types in Protocol Buffers. We cover key concepts, practical examples, and best practices to help you master this topic.

Nested types in Protocol Buffers allow defining messages, enums, and oneofs inside other messages. This provides logical grouping, prevents name collisions, and communicates that the nested type belongs to its parent context.

What You'll Learn

  • Defining nested messages, enums, and oneofs
  • Accessing nested types from generated code
  • Nesting depth best practices
  • When to use nested vs top-level types

Why It Matters

Nested types keep the proto file organized and make the schema more readable. They signal ownership and scope. Too much nesting creates verbose generated code.

Real-World Use

Google's Api Design guidelines recommend nesting types that are only used as helper types within a parent message. The gRPC health.proto uses nested messages for request and response types.

flowchart LR
    Message[Parent Message] --> NestedMsg[Nested Message]
    Message --> NestedEnum[Nested Enum]
    Message --> NestedOneof[Nested Oneof]
    NestedMsg --> CodeMsg[Generated: Parent.NestedMsg]
    NestedEnum --> CodeEnum[Generated: Parent.NestedEnum]

Teacher Mindset

Nest types when they exist only as helpers for the parent. Keep nesting at most two levels deep. If a type is used by multiple parent messages, make it top-level.

Code Examples

// Example 1: Multi-level nesting
message Library {
  message Book {
    string id = 1;
    string title = 2;
    string isbn = 3;

    enum Genre {
      GENRE_UNSPECIFIED = 0;
      FICTION = 1;
      NON_FICTION = 2;
      SCIENCE = 3;
    }

    Genre genre = 4;

    message Author {
      string name = 1;
      string bio = 2;
    }

    Author author = 5;
  }

  message Member {
    string id = 1;
    string name = 2;
  }

  string name = 1;
  repeated Book books = 2;
  repeated Member members = 3;
}
// Example 2: Nested oneof in message
message Payment {
  string id = 1;

  oneof method {
    CreditCard card = 2;
    PayPal paypal = 3;
    Crypto crypto = 4;
  }

  message CreditCard {
    string number = 1;
    string expiry = 2;
    string cvv = 3;
  }

  message PayPal {
    string email = 1;
  }

  message Crypto {
    string wallet_address = 1;
    string currency = 2;
  }
}
# Example 3: Accessing nested types in Python
from library_pb2 import Library

# Access nested messages
book = Library.Book()
book.title = "GraphQL in Action"
book.genre = Library.Book.Genre.FICTION

author = Library.Book.Author()
author.name = "John Doe"
book.author.CopyFrom(author)

library = Library()
library.name = "Central Library"
library.books.append(book)

Common Mistakes

  • Nesting types three or more levels deep, making code verbose
  • Defining a nested type that is used outside the parent message
  • Using nested types when the parent message is already very large
  • Forgetting to use the full path to access nested types in generated code
  • Mixing nested and top-level types inconsistently within a project

Practice

  1. Create a School message with a nested Student message.
  2. Add a nested enum Grade to Student.
  3. Add a nested oneof Contact to Student for email or phone.
  4. Access the nested types in your language's generated code.
  5. Challenge: Design a Company message with deeply nested Department, Employee, and Project messages.

FAQ

Can I reference a nested type from another file?

No. Nested types are scoped to their parent message. To reuse a type across files, define it at the top level.

How deep should I nest messages?

Max 2 levels. Deep nesting generates long type names like Parent.Child.Grandchild and reduces readability.

Can I have both nested and top-level types in the same file?

Yes. Use top-level for shared types and nested for types specific to their parent.

Are nested types backward compatible?

If you change a nested type, it affects only the parent message. This is safe as long as field numbers are not reused.

How do nested types affect code generation?

Nested types become inner classes (Java), nested classes (C++), or attributes on the parent (Python).

Mini Project

Refactor your order management protos to use nested types. Put OrderItem inside Order, ShippingAddress inside Order, and PaymentMethod as a nested oneof inside Payment. Ensure all types are at most 2 levels deep.

What's Next

Next, you will learn about defining services in .proto files for gRPC endpoints.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro