95 lines
3.8 KiB
Markdown
95 lines
3.8 KiB
Markdown
|
# Making API Changes
|
||
|
|
||
|
This document describes the process of how btcwallet developers must make
|
||
|
changes to the RPC API and server. Due to the use of gRPC and Protocol Buffers
|
||
|
for the RPC implementation, changes to this API require extra dependencies and
|
||
|
steps before changes to the server can be implemented.
|
||
|
|
||
|
## Requirements
|
||
|
|
||
|
- The Protocol Buffer compiler `protoc` installed with support for the `proto3`
|
||
|
language
|
||
|
|
||
|
The `protoc` tool is part of the Protocol Buffers project. This can be
|
||
|
installed [from source](https://github.com/google/protobuf/blob/master/INSTALL.txt),
|
||
|
from an [official binary release](https://github.com/google/protobuf/releases),
|
||
|
or through an operating system's package manager.
|
||
|
|
||
|
- The gRPC `protoc` plugin for Go
|
||
|
|
||
|
This plugin is written in Go and can be installed using `go get`:
|
||
|
|
||
|
```
|
||
|
go get github.com/golang/protobuf/protoc-gen-go
|
||
|
```
|
||
|
|
||
|
- Knowledge of Protocol Buffers version 3 (proto3)
|
||
|
|
||
|
Note that a full installation of gRPC Core is not required, and only the
|
||
|
`protoc` compiler and Go plugins are necessary. This is due to the project
|
||
|
using a pure Go gRPC implementation instead of wrapping the C library from gRPC
|
||
|
Core.
|
||
|
|
||
|
## Step 1: Modify the `.proto`
|
||
|
|
||
|
Once the developer dependencies have been met, changes can be made to the API by
|
||
|
modifying the Protocol Buffers descriptor file [`api.proto`](../api.proto).
|
||
|
|
||
|
The API is versioned according to the rules of [Semantic Versioning
|
||
|
2.0](http://semver.org/). After any changes, bump the API version in the [API
|
||
|
specification](./api.md) and add the changes to the spec.
|
||
|
|
||
|
Unless backwards compatibility is broken (and the version is bumped to represent
|
||
|
this change), message fields must never be removed or changed, and new fields
|
||
|
must always be appended.
|
||
|
|
||
|
It is forbidden to use the `required` attribute on a message field as this can
|
||
|
cause errors during parsing when the new API is used by an older client.
|
||
|
Instead, the (implicit) optional attribute is used, and the server
|
||
|
implementation must return an appropiate error if the new request field is not
|
||
|
set to a valid value.
|
||
|
|
||
|
## Step 2: Compile the `.proto`
|
||
|
|
||
|
Once changes to the descriptor file and API specification have been made, the
|
||
|
`protoc` compiler must be used to compile the descriptor into a Go package.
|
||
|
This code contains interfaces (stubs) for each service (to be implemented by the
|
||
|
wallet) and message types used for each RPC. This same code can also be
|
||
|
imported by a Go client that then calls same interface methods to perform RPC
|
||
|
with the wallet.
|
||
|
|
||
|
By committing the autogenerated package to the project repo, the `proto3`
|
||
|
compiler and plugin are not needed by users installing the project by source or
|
||
|
by other developers not making changes to the RPC API.
|
||
|
|
||
|
A `sh` shell script is included to compile the Protocol Buffers descriptor. It
|
||
|
must be run from the `rpc` directory.
|
||
|
|
||
|
```bash
|
||
|
$ sh regen.sh
|
||
|
```
|
||
|
|
||
|
If a `sh` shell is unavailable, the command can be run manually instead (again
|
||
|
from the `rpc` directory).
|
||
|
|
||
|
```
|
||
|
protoc -I. api.proto --go_out=plugins=grpc:walletrpc
|
||
|
```
|
||
|
|
||
|
TODO(jrick): This step could be simplified and be more portable by putting the
|
||
|
commands in a Go source file and executing them with `go generate`. It should,
|
||
|
however, only be run when API changes are performed (not with `go generate
|
||
|
./...` in the project root) since not all developers are expected to have
|
||
|
`protoc` installed.
|
||
|
|
||
|
## Step 3: Implement the API change in the RPC server
|
||
|
|
||
|
After the Go code for the API has been regenated, the necessary changes can be
|
||
|
implemented in the [`rpcserver`](../rpcserver/) package.
|
||
|
|
||
|
## Additional Resources
|
||
|
|
||
|
- [Protocol Buffers Language Guide (proto3)](https://developers.google.com/protocol-buffers/docs/proto3)
|
||
|
- [Protocol Buffers Basics: Go](https://developers.google.com/protocol-buffers/docs/gotutorial)
|
||
|
- [gRPC Basics: Go](http://www.grpc.io/docs/tutorials/basic/go.html)
|