Protobuf,Go和私有字段

Let's say I've got a Player defined in my .proto file.

message Player {
  string first_name = 1;
  string last_name = 2;
  int32 user_id = 3;
}

I'm using https://github.com/twitchtv/twirp to communicate between my Go backend and my JavaScript frontend. If you don't know Twirp it's simply JSON RPC over HTTP 1.1.

The Player message is converted into a Go struct

type Player struct {
  FirstName string
  LastName string
  UserId int32
}

As we all know uppercase fields are public. However I'd like to keep the UserId private, i.e. make it lowercase. My users in the frontend should not be able to see the UserId of a player. In my backend I need this information so I cannot simply remove the field.

Any ideas how to handle such a situation? Is it possible to have private fields in my .proto files?

Protobuf is for communication, not for database modeling. You should use protobuf to describe the data structures you intend to send over / receive from your clients.

If you don't intend to send the user ID to the clients, don't include that in your protobuf Player definition.

The Player you send to the clients and the Player you store in your database does not have to be the same. More often they are not the same, you usually store other fields such as creation time, database ID etc. which are not for the clients.

So you should have 2 separate structures for a Player, one that the server uses (stores), and one that clients see. Of course when defining those 2 structs, you may utilize one in the other to prevent repetition, e.g. the server player may embed the client player, e.g.:

New proto Player:

message Player {
  string first_name = 1;
  string last_name = 2;
}

Client Player:

type Player struct {
    FirstName string
    LastName string
}

Server Player:

type DBPlayer struct {
    Player // Embed Player

    UserId int32
}

And when you load a DBPlayer in your server, you would only send the DBPlayer.Player field to the client, the rest is "private".