Skip to content

Commit

Permalink
Refactor buf commands to take inputs as first argument (#174)
Browse files Browse the repository at this point in the history
  • Loading branch information
bufdev authored Oct 30, 2020
1 parent 1ecf3c7 commit dafbb54
Show file tree
Hide file tree
Showing 20 changed files with 990 additions and 324 deletions.
113 changes: 49 additions & 64 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,21 @@
more details.**

## Goal
---

Buf's goal is for Protobuf to not only be a good choice on the technical merits,
but to be so easy to use that the decision is trivial. Your organization
should not have to reinvent the wheel to use Protobuf efficiently and effectively. Stop
worrying about your Protobuf management strategy getting out of control. We'll
handle that for you, so you can worry about what matters.
Buf’s long-term goal is to enable schema-driven development: a future where APIs are defined consistently, in a way that service owners and clients can depend on.

Defining APIs using an [IDL](https://en.wikipedia.org/wiki/Interface_description_language) provides a number of benefits over simply exposing JSON/REST services, and today, [Protobuf](https://developers.google.com/protocol-buffers) is the most stable, widely-adopted IDL in the industry.

However, as it stands, using Protobuf is much more difficult than using JSON as your data transfer format.

Enter Buf: We’re building tooling to make Protobuf reliable and easy to use for service owners and clients, while keeping it the obvious choice on the technical merits.

Your organization should not have to reinvent the wheel to create, maintain, and consume Protobuf APIs efficiently and effectively. We'll handle your Protobuf management strategy for you, so you can focus on what matters.

We’re working quickly to build a modern Protobuf ecosystem. Our first tool is the **Buf CLI**, built to help you create consistent Protobuf APIs that preserve compatibility and comply with design best-practices. The tool is currently available on an open-source basis.

Our second tool, the **Buf Schema Registry (“BSR”)**, will be the hub of our ecosystem. The BSR is a platform that serves as the source of truth for your organization's Protobuf files, enabling you to centrally maintain compatibility and manage dependencies, while enabling your clients to consume APIs reliably and efficiently. The BSR will be available for a limited, free private beta shortly.


## Quick Links
Expand All @@ -35,62 +44,35 @@ However, we recommend you read the below introduction first!
- [Migration from Protolock](https://buf.build/docs/migration-protolock)
- [Migration from Prototool](https://buf.build/docs/migration-prototool)

## Overview
## The problems we aim to solve

Traditionally, adopting Protobuf presents a number of challenges across the API lifecycle. These are the problems we aim to solve.

Using an [IDL](https://en.wikipedia.org/wiki/Interface_description_language) such as
[Protocol Buffers](https://developers.google.com/protocol-buffers) ("Protobuf")
provides numerous benefits over JSON:
### Creating consistent Protobuf APIs

- Generated stubs for each language you use.
- Forwards and backwards compatibility for your data types.
- Payload sizes are up to 10 times smaller.
- Serialization speed is up to 100 times faster.
- Structured RPCs for your APIs instead of documented HTTP endpoints.
- **API designs are often inconsistent**: Writing maintainable, consistent Protobuf APIs isn't as widely understood as writing maintainable JSON/REST-based APIs. With no standards enforcement, inconsistency can arise across an organization's Protobuf APIs, and design decisions can inadvertantly affect your API's future iterability.

Protobuf is the most stable, widely-adopted IDL in the software industry today. While there are
many pros and cons to Protobuf versus other IDLs such as Thrift, FlatBuffers, Avro, and Cap'n Proto,
Protobuf provides most companies the most stable platform to build on, along with the largest
ecosystem of languages and libraries available.
### Maintaining compatible, accessible Protobuf APIs

If you've found us today, we'll assume you're already relatively convinced of these statements.
We'll add a reference document for those new to Protobuf in the future.
- **Dependency management is usually an afterthought**: Protobuf files are vendored manually, with an error-prone copy-and-paste process from Github repositories. There is no centralized attempt to track and manage around cross-file dependencies.

If Protobuf is so great, the question is: why do so many companies still choose JSON as their
data format in 2020? Usually, the answer comes down to difficulty in adoption:
- **Forwards and backwards compatibility is not enforced**: While forwards and backwards compatibility is a promise of Protobuf, actually maintaining backwards-compatible Protobuf APIs isn't widely practiced, and is hard to enforce.

- **API Structure**: Writing maintainable, consistent Protobuf APIs isn't as widely
understood as writing maintainable JSON/REST-based APIs, which makes sense - Protobuf
is not as widely adopted. With no standards enforcement, inconsistency can arise across
an organization's Protobuf APIs, and design decisions can be made that can affect your
API's future iterability.
- **Backwards compatibility**: While forwards and backwards compatibility is a promise
of Protobuf, actually maintaining backwards-compatible Protobuf APIs isn't widely
practiced, and is hard to enforce.
- **Stub distribution**: Maintaining consistent stub generation is a difficult proposition.
There is a steep learning curve to using `protoc` and associated plugins in a maintainable manner.
Organizations end up struggling with distribution of Protobuf files and stubs, even if they use a
build system such as Bazel - exposing APIs to external customers remains problematic.
It ends up being more trouble than it's worth to expose APIs via Protobuf than via JSON/REST.
- **Tooling**: Lots of tooling for JSON/REST APIs exists today and is easy to use.
Mock server generation, fuzz testing, documentation, and other daily API concerns
are not widely standardized and easy to use for Protobuf APIs.
### Consuming Protobuf APIs efficiently and reliably

Done right, adopting Protobuf to represent
your structured data and APIs can quite literally produce one of the largest efficiency gains your
engineering organization can have. Much of the software we write today can be generated, and many
daily software development tasks we perform can be automated away.
- **Stub distribution is a difficult, unsolved process**: Organizations have to choose to either centralize the protoc workflow and distribute generated code, or require all service clients to run protoc independently. Because there is a steep learning curve to using protoc and associated plugins in a reliable manner, organizations end up choosing to struggle with distribution of Protobuf files and stubs. This creates substantial overhead, and often requires a dedicated team to manage the process. Even when using a build system like Bazel, exposing APIs to external customers remains problematic.

In time, Buf aims to solve all this and more. However, there is a long way between that
world and the one we have now.
- **The tooling ecosystem is limited**: Lots of easy-to-use tooling exists today for JSON/REST APIs. Mock server generation, fuzz testing, documentation, and other daily API concerns are not widely standardized and easy to use for Protobuf APIs, requiring teams to regularly reinvent the wheel and build custom tooling to replicate the JSON ecosystem.

## Buf CLI

Phase 1 is to solve the API Structure and Backwards Compatibility problems: let's
help you maintain consistent Protobuf APIs that maintain compatibility.
## Buf is building a modern Protobuf ecosystem

This is done via the Buf CLI tool.
Our tools will address many of the problems above, ultimately allowing you to redirect much of your time and energy from managing Protobuf files to implementing your core features and infrastructure.

Buf currently contains:

### The Buf CLI

The Buf CLI incorporates the following components to help you create consistent Protobuf APIs:

- A [linter](https://buf.build/docs/lint-usage) that enforces good API design choices and structure.
- A [breaking change detector](https://buf.build/docs/breaking-usage) that enforces compatibility at the source code or wire level.
Expand All @@ -102,59 +84,62 @@ Buf currently contains:
[Images](https://buf.build/docs/build-images), our extension of
[FileDescriptorSets](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/descriptor.proto).

Buf is designed to be extremely simple to use, while providing functionality for advanced use cases.
Features of Buf's include:
The Buf CLI is designed to be extremely simple to use, while providing functionality for advanced use cases. Features of the CLI include:

- **Automatic file discovery**. By default, Buf will build your `.proto` files by walking your file
- **Automatic file discovery**: By default, Buf will build your `.proto` files by walking your file
tree and building them per your [build configuration](https://buf.build/docs/build-configuration). This means you no longer need to
manually specify your `--proto_paths` and files every time you run the tool. However, Buf does
allow manual file specification through command-line flags if you want no file discovery to
occur, for example in Bazel setups.

- **Selectable configuration** of the exact lint and breaking change configuration you want.
- **Selectable configuration**: of the exact lint and breaking change configuration you want.
While we recommend using the defaults, Buf allows you to easily understand and select the exact set
of lint and breaking change checkers your organization needs.

Buf provides [40 available lint checkers](https://buf.build/docs/lint-checkers) and [54 available breaking
checkers](https://buf.build/docs/breaking-checkers) to cover most needs. We believe our breaking change detection truly
covers every scenario for your APIs.

- **Selectable error output**. By default, Buf outputs `file:line:col:message` information
- **Selectable error output**: By default, Buf outputs `file:line:col:message` information
for every lint error and every breaking change, with the file path carefully outputted to
match the input location, including if absolute paths are used, and for breaking change detection,
including if types move across files. JSON output that includes the end line and end column
of the lint error is also available, and JUnit output is coming soon.

- **Editor integration**. The default error output is easily parseable by any editor, making the
- **Editor integration**: The default error output is easily parseable by any editor, making the
feedback loop for issues very short. Currently, we only provide [Vim integration](https://buf.build/docs/editor-integration)
for linting but will extend this in the future to include other editors such as Emacs, VS Code,
and Intellij IDEs.

- **Check anything from anywhere**. Buf allows you to not only check a Protobuf schema stored
- **Check anything from anywhere**: Buf allows you to not only check a Protobuf schema stored
locally as `.proto` files, but allows you to check many different [Inputs](https://buf.build/docs/inputs):

- Tar or zip archives containing `.proto` files, both local and remote.
- Git repository branches or tags containing `.proto` files, both local and remote.
- Pre-built [Images](https://buf.build/docs/build-images) or FileDescriptorSets from `protoc`, from both local and remote
(http/https) locations.

- **Speed**. Buf's [internal Protobuf compiler](https://buf.build/docs/build-compiler) utilizes all available cores to compile
- **Speed**: Buf's [internal Protobuf compiler](https://buf.build/docs/build-compiler) utilizes all available cores to compile
your Protobuf schema, while still maintaining deterministic output. Additionally files are copied into
memory before processing. As an unscientific example, Buf can compile all 2,311 `.proto` files in
[googleapis](https://github.com/googleapis/googleapis) in about **0.8s** on a four-core machine,
as opposed to about 4.3s for `protoc` on the same machine. While both are very fast, this allows for
instantaneous feedback, which is especially useful with editor integration. Buf's speed is
directly proportional to the input size, so checking a single file only takes a few milliseconds.

## Buf Schema Registry
### The Buf Schema Registry

The Buf Schema Registry will be a powerful hosted SaaS platform to serve as your organization’s source of truth for your Protobuf APIs, built around the primitive of Protobuf Modules. We’re introducing the concept of Protobuf Modules to enable the BSR to manage a group of Protobuf files together, similar to a Go Module.

Initially, the BSR will offer the following key features:

- **Centrally managed dependencies**: Resolve diamond dependency issues caused by haphazard versioning, even with external repository dependants.

- **Automatically enforce forwards and backwards compatibility**: Ensure API clients never break, without wasteful team-to-team communication or custom SLAs.

The Buf CLI is just the first component of Buf's modern Protobuf ecosystem. We're currently
in private beta of the **Buf Schema Registry**, a hosted and on-prem service that managed
the new Protobuf Modules paradigm. The Buf Schema Registry allows you to push and consume
modules, enabling entirely new Protobuf workflows.
- **Generated libraries produced by a managed compiler**: Language-specific stub generation using Buf’s high-performance, drop-in protoc replacement.

There's a lot we are planning with the Buf Schema Registry. For a quick overview, see our
[roadmap](https://buf.build/docs/roadmap).
Over time, our goal is to make the BSR the only tool you need to manage your Protobuf workflow from end to end. To that end, there's a lot we are planning with the Buf Schema Registry. For a quick overview, see our [roadmap](https://buf.build/docs/roadmap).

## Where to go from here

Expand Down
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ require (
github.com/golang/protobuf v1.4.3
github.com/google/go-cmp v0.5.2
github.com/jhump/protoreflect v1.7.1-0.20200723220026-11eaaf73e0ec
github.com/klauspost/compress v1.11.1
github.com/klauspost/compress v1.11.2
github.com/klauspost/pgzip v1.2.5
github.com/pkg/profile v1.5.0
github.com/spf13/cobra v1.0.1-0.20201006035406-b97b5ead31f7
Expand All @@ -19,9 +19,9 @@ require (
go.uber.org/multierr v1.6.0
go.uber.org/zap v1.16.0
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
golang.org/x/sys v0.0.0-20201020230747-6e5568b54d1a // indirect
golang.org/x/sys v0.0.0-20201029080932-201ba4db2418 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
google.golang.org/genproto v0.0.0-20201021134325-0d71844de594 // indirect
google.golang.org/genproto v0.0.0-20201030142918-24207fddd1c3 // indirect
google.golang.org/protobuf v1.25.0
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776
)
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.11.1 h1:bPb7nMRdOZYDrpPMTA3EInUQrdgoBinqUuSwlGdKDdE=
github.com/klauspost/compress v1.11.1/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.11.2 h1:MiK62aErc3gIiVEtyzKfeOHgW7atJb5g/KNX5m3c2nQ=
github.com/klauspost/compress v1.11.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE=
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
Expand Down Expand Up @@ -307,8 +307,8 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201020230747-6e5568b54d1a h1:e3IU37lwO4aq3uoRKINC7JikojFmE5gO7xhfxs8VC34=
golang.org/x/sys v0.0.0-20201020230747-6e5568b54d1a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201029080932-201ba4db2418 h1:HlFl4V6pEMziuLXyRkm5BIYq1y1GAbb02pRlWvI54OM=
golang.org/x/sys v0.0.0-20201029080932-201ba4db2418/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
Expand Down Expand Up @@ -368,8 +368,8 @@ google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBr
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20201021134325-0d71844de594 h1:JZWUHUjZJojCHxs9ZZLFsnRGKVBXBoOHGxeTSt6OE+Q=
google.golang.org/genproto v0.0.0-20201021134325-0d71844de594/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201030142918-24207fddd1c3 h1:sg8vLDNIxFPHTchfhH1E3AI32BL3f23oie38xUWnJM8=
google.golang.org/genproto v0.0.0-20201030142918-24207fddd1c3/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
Expand Down
2 changes: 1 addition & 1 deletion internal/buf/bufconfig/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func (p *provider) newConfigV1Beta1(externalConfig externalConfigV1Beta1) (*Conf
func (p *provider) validateExternalConfigVersion(externalConfigVersion externalConfigVersion, id string) error {
switch externalConfigVersion.Version {
case "":
p.logger.Sugar().Warnf(`%s has no version set. Please add "version: %s". See https://buf.build/docs/faq for more details.`, id, v1beta1Version)
p.logger.Sugar().Warnf(`%s has no version set. Please add "version: %s". See https://docs.buf.build/faq for more details.`, id, v1beta1Version)
return nil
case v1beta1Version:
return nil
Expand Down
Loading

0 comments on commit dafbb54

Please sign in to comment.