Defining API Endpoints
🔗 Defining API Endpoints
Protobufs are used to define APIs, using the service
and rpc
constructs, along with custom- and Google-based protos for HTTP related features. For each rpc
defined in a service
proto, a corresponding handler file needs to be created in a /go/pkg/handlers
file. See existing handlers for examples.
Existing protos use a standard method of defining service RPCs and then the input/output messages for each individual RPC. Care must be taken when designing an API in such a way that it doesn’t become too large and cumbersome. Input and output messages should be simple, containing a few properties each, with specific purposes in mind.
External Properties
Use of Google-based proto annotations can be researched online, as well as studied in existing protos, and include:
google/protobuf/struct.proto
google/api/annotations.proto
google/api/field_behavior.proto
Custom Properties
Custom properties are further defined in the util.proto
:
cache: By default, the server will cache all GET requests for 180 seconds.
- DEFAULT - Default behavior.
- SKIP - Never cache endpoint responses.
- STORE - Permanently cache response in Redis, and use that on subsequent GETs.
cache_duration: Seconds. Used to override default 180 second cache duration for GET requests.
throttle: Todo. Throttles endpoint for 10 requests per n seconds.
siteRole: Limit access to a particular site role. Check util.proto
for current values.
Following our example, we might create a service for our Todos like this:
service TodoService {
rpc PostTodo(PostTodoRequest) returns (PostTodoResponse) {
option (google.api.http) = {
post: "/v1/todos"
body: "*"
};
}
rpc GetTodos(GetTodosRequest) returns (GetTodosResponse) {
option (google.api.http) = {
get: "/v1/todos"
};
}
rpc DeleteTodo(DeleteTodoRequest) returns (DeleteTodoResponse) {
option (google.api.http) = {
delete: "/v1/todos/{id}"
};
}
}
And its corresponding input/output objects:
message PostTodoRequest {
ITodo todo = 1 [(google.api.field_behavior) = REQUIRED];
}
message PostTodoResponse {
string id = 1 [(google.api.field_behavior) = REQUIRED];
bool done = 2 [(google.api.field_behavior) = REQUIRED];
}
message GetTodosRequest {}
message GetTodosResponse {
repeated ITodo todos = 1 [(google.api.field_behavior) = REQUIRED];
}
message DeleteTodoRequest {
string id = 1 [(google.api.field_behavior) = REQUIRED];
}
message DeleteTodoResponse {
string id = 1 [(google.api.field_behavior) = REQUIRED];
}