Files and Packages

Organize your protobuf files consistently for maintainability and clarity.

File Naming

  • Use snake_case.proto for filenames
  • File names should be descriptive: user_service.proto, not service.proto
  • Version in filename is discouraged: use packages for versioning

File Structure

// File: user_service.proto

// 1. License header (if applicable)
// 2. File-level comments

// 3. Syntax declaration
syntax = string">"proto3";

// 4. Package declaration
package company.user.v1;

// 5. Imports (sorted: standard, then custom)
import string">"google/protobuf/empty.proto";
import string">"google/protobuf/timestamp.proto";

import string">"common/pagination.proto";
import string">"common/validation.proto";

// 6. File options
option go_package = string">"github.com/company/api/user/v1;userv1";
option java_package = string">"com.company.api.user.v1";
option java_multiple_files = true;

// 7. Service definition(s)
// 8. Request/Response messages
// 9. Resource messages
// 10. Enums

One Service Per File

Each service should be in its own file with its request/response messages. Shared messages go in separate files.

user_service.proto    # Service definition + request/response
user.proto           # User message definition
user_events.proto    # Event messages
common/errors.proto  # Shared error messages

File Structure

Organize your protobuf files for clarity and maintainability. A well-structured schema is easier to navigate and extend.

File Organization

Recommended Directory Structure

proto/
├── common/
│   ├── pagination.proto
│   ├── errors.proto
│   └── metadata.proto
├── user/
│   ├── user.proto
│   ├── user_service.proto
│   └── user_events.proto
├── order/
│   ├── order.proto
│   ├── order_service.proto
│   └── order_events.proto
└── README.md

File Layout

Each .proto file should follow this standard layout:

syntax = string">"proto3";

package company.service.v1;

import string">"google/protobuf/timestamp.proto";
import string">"google/protobuf/empty.proto";
import string">"common/pagination.proto";

// File-level options
option go_package = string">"github.com/company/api/service/v1;servicev1";
option java_package = string">"com.company.api.service.v1";
option java_multiple_files = true;

// Service definition (if applicable)
service UserService {
  // RPCs grouped by functionality
  rpc GetUser(GetUserRequest) returns (GetUserResponse);
  rpc ListUsers(ListUsersRequest) returns (ListUsersResponse);
}

// Request/Response messages
message GetUserRequest {
  string user_id = 1;
}

message GetUserResponse {
  User user = 1;
}

// Core data messages
message User {
  string id = 1;
  string email = 2;
  string name = 3;
  UserStatus status = 4;
  google.protobuf.Timestamp created_at = 5;
}

// Enums at the bottom
enum UserStatus {
  USER_STATUS_UNSPECIFIED = 0;
  USER_STATUS_ACTIVE = 1;
  USER_STATUS_INACTIVE = 2;
}

Import Guidelines

  • Group imports: standard protobuf imports first, then your custom imports
  • Use relative imports for files in the same package
  • Avoid circular dependencies between proto files
  • Keep common types in separate files for reusability