Package Types
Buffrs makes distinctions between two different packages:
[package]
type = "lib" | "api"
This is used in order to fuel composition and type reuse across APIs and thus enable shared types + wire compatibility.
lib
– Libraries
Libraries contain atomic and composite type definitions that describe a domain.
(e.g. physics
, auth
, time
etc.). This pattern is really useful for
scaling systems and maintaining dozens of APIs as they can share types and thus
get the aforementioned benefits of source code and wire compatibility for free.
An example of a proto library named time
that depends on google
:
[package]
name = "time"
type = "lib"
version = "1.0.0"
[dependencies]
google = { version = "=1.0.0", ... }
syntax = "proto3";
package time;
import "google/timestamp.proto";
/// A timestamp wrapper for various formats
message Time {
oneof format {
string rfc3339 = 1;
uint64 unix = 2;
google.protobuf.Timestamp google = 3;
..
}
}
api
– APIs
APIs are the next logical building block for real world systems – they define services and RPCs that your server can implement. You can use the aforementioned libraries to fuel your development / API definition experience.
A good example of an API could be an imaginary logging
service that makes use
of the just declared time.Time
:
[package]
name = "logging"
type = "api"
version = "1.0.0"
[dependencies]
time = { version = "=1.0.0", ... }
syntax = "proto3";
package logging;
import "time/time.proto";
service Logging {
rpc critical(LogInput) returns (LogOutput);
rpc telemetry(LogInput) returns (LogOutput);
rpc healthiness(HealthInput) returns (HealthOutput);
}
message LogInput { string context = 1; time.Time timestamp = 2; }
message LogOutput { }
message HealthInput { bool db = 1; }
message HealthOutput { }