Protobuf is a mini-language for defining structs and services.
https://developers.google.com/protocol-buffers
An example definition is:
```
message Foo {
required int32 bar = 1;
optional string baz = 2;
}
``
This is defining a struct named Foo, with fields bar and baz. '1' and '2' are identifiers for the fields.
The proto compiler allows compilation into most common languages, so a single definition of a struct can be easily shared. This allows all languages using the API to avoid having their own custom wrapper, which both provides type safety and is just easier to work with.
Besides structs, protobuf also supports defining services. These are essentially an interface which can be compiled to different languages. The underlying implementation of the service is not defined by the proto file, so any implementation can be made. For WikiTree api, the service could be:
```wikitree.proto
service WikiTree {
rpc GetProfile(GetProfileRequest) returns GetProfileResponse {}
rpc GetPerson(GetPersonRequest) returns (GetPersonResponse) {}
// ... other actions
}
message GetProfileRequest {
string key = 1;
string fields = 2;
string bio_format = 3;
string resolve_redirect = 4;
}
message GetProfileResponse {
string id = ;
int64 page_id = 2;
string name = 3;
// ... etc
}
// ... other Requests and Responses.
```
The advantage to having a proto definition like this, is that pretty much any language could use the API very easily. All of the structs and client code would be shared. The only thing that would need to be custom per-language would be what's needed to set up an initial connection, and to authenticate.
It would take a bit of work to put together the authentication bits, but using the end result would look something like:
```example.go
func main() {
// Creating a client would handle authentication and would internally store the token.
// The client would implement the WikiTreeClientInterface, which is generated by the protobuf compiler based on the service definition in the '.proto' file.
client, err := NewWikiTreeClient(username, password)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
// resp is a GetProfileResponse struct, which is from the `message GetProfileResponse` defined in the '.proto' file.
resp, err := client.GetProfile(&pb.GetProfileRequest{key: "Mustardo-1"})
fmt.Println(resp)
}
```
Is this something that folks have looked into? I may try putting together a proof of concept for a subset of the API.