Twirp Versions Save

A simple RPC framework with protobuf service definitions

v8.1.3

1 year ago

What's Changed

New Contributors

Full Changelog: https://github.com/twitchtv/twirp/compare/v8.1.2...v8.1.3

v8.1.2

2 years ago

What's Changed

New Contributors

Full Changelog: https://github.com/twitchtv/twirp/compare/v8.1.1...v8.1.2

v8.1.1

2 years ago

Changes:

  • New supported client languages were added to the README: TwirpScript (Javascript/Typescript) PR 331 & PR-334, Swift PR-337
  • Add support for field presence in protobuf files PR-332. Note: This is simply a feature flag to prevent protoc from returning an error when the option is used with twirp. No change to the generated code or runtime library was necessary.
  • Don't check error when closing the response Body, PR-336. This works around an upstream issue in Go 1.16.10 and Go 1.17.3.
  • New Error Constructors: code.Error(msg) and code.Errorf(msg, a...). PR-339
  • Several minor doc changes: PR 340, PR-343, PR 341

v8.1.0

2 years ago

Changes:

  • PR #323: Match service errors with errors.As instead of a type cast. Service implementations can now use their own error types if they implement the twirp.Error interface, but also if they wrap another Twirp error, or if theyimplement the method As(interface{}) bool. See docs on Twirp Erros for more details.
  • PR #299: ServerOption twirp.WithServerJSONCamelCaseNames(true) configures JSON serialization to use the proto3 standard serialization method instead of the Twirp default to use the original proto names. When enabled, the JSON field names will be lowerCamelCase by default. If the json_name field option is used in the proto file, the specified value will be used as the key instead.
  • PR #318: Removed example Python client generator. This repo contains the Go implementation only now.
  • PR #319 refactors ServerOptions and ClientOptions to allow new options in the future without forcing version updates.
  • PR #321 and #313 improves and simplifies the CI build process, running clientcompat tests and removing faulty coverage checks.
  • PR #312 sorts generated code imports so the generator always produces the same output.

Update instructions:

  • Required Go version 1.13+ is needed for the errors package Is/As/Unwrap functions.
  • Runtime library is backwards compatible, can be safely updated to v8.1.0.
  • Generated clients are backwards compatible, but will require the importer to update their Twirp runtime library.
  • The PR #323 introduces a potential breaking change for services. Read below for safe update instructions.

Previous Twirp services (v8.0.0 and older) check if returned errors are Twirp errors with a type-cast:

twerr, ok := err.(twirp.Error)

Newer Twirp services (v8.1.0) will check if returned errors are Twirp errors by matching with errors.As:

var twerr twirp.Error
ok := errors.As(err, &twerr)

Matching with errors.As is similar to the type-cast, but it can also unwrap errors of the same type. Before you update to version v8.1.0, please double check if any non-twirp errors returned by your service are not accidentally wrapping another Twirp error that should not be returned on the API. In particular, look for instances of fmt.Errorf("foo: %w", twerr), using %w for wrapping other Twirp errors, for example:

// Calling another Twirp service from a Twirp method handler
resp, clientErr := anotherService.MyMethod(ctx, req)
if clientErr != nil {
    // Wrapping another Twirp error will expose the inner error on v8.1.0
    err := fmt.Errorf("otherService: %w", clientErr)
    return nil, err
}

If you believe your service may be mistakenly wrapping other Twirp errors, you can explicitly wrap the error as an internal:

    return nil, twirp.InternalErrorWith(err)

You could also use this error hook to identify possible discrepancies before updating to the new version. In the other hand, if your service was already using idiomatic Go errors, the new implementation will give you more power to your own Twirp error implementations.

v8.0.0

3 years ago

PR #304: Twirp v8 generates code that depends on Protobuf APIv2 (instead of APIv1).

Update Instructions

The runtime library github.com/twitchtv/twirp does not have any changes. The new generated code works with both old and new versions of the runtime library.

Re-generate code with Twirp v8 and Protobuf APIv2:

  • Install the new protoc-gen-go plugin: go install google.golang.org/protobuf/cmd/protoc-gen-go@latest.
  • Install the new protoc-gen-twirp plugin: go install github.com/twitchtv/twirp/protoc-gen-twirp@latest.
  • Re-generate code. For example: protoc --go_out=paths=source_relative:. --twirp_out=paths=source_relative:. service.proto

See Install docs for more information.

Generated clients and services will use the new imports: google.golang.org/protobuf (APIv2). Projects that make use of the generated clients/servers will have to update their import paths.

The new google.golang.org/protobuf (APIv2) is mostly backwards compatible, but not completely. You may have to make additional changes to work with the new protobuf library:

  • In the proto file, the option go_package is mandatory and must include a "/" (it is supposed to be a full import path). If you have to add a full path to the go_package, you may want to generate with the options paths=source_relative. For example: protoc --go_out=. --go_opt=paths=source_relative --twirp_out=. --twirp_opt=paths=source_relative myfile.proto
  • Generated message models (structs) now contain a mutex, your linter may complain if the models are copied by value. The solution is to pass pointers instead. Using reflect.DeepEqual will not be able to compare protobuf, you can use proto.Equal instead.
  • Check protobuf go compatibility and their releases for more details.

v7.2.0

3 years ago
  • PR #294: handling and returning valid error code for context.Canceled and context.DeadlineExceeded during body read error, and returning meaningful error 4XX instead of a 5XX error.

v7.1.1

3 years ago
  • PR #288

v7.1.0

3 years ago
  • PR #276 implements interceptors, an elegant way to plugin new functionality to clients and services with a simple but powerful interface.
  • PR #277, fixing #257 on the client side, allowing Go clients to talk to services implemented in different languages (e.g. Python) when the proto definition contains Service and Method names that are not CamelCased. Note that only Go services generated with v7 can handle literal routes, previous versions only support CamelCased routes.

v7.0.0

3 years ago

Twirp v7 is a major release that includes a protocol spec update. The jump from v5 to v7 is to avoid confusion with the archived protocol spec v6 that was not released.

Changes in the protocol spec from v5 to v7:

  • Twirp routes can have any prefix: <prefix>/<package>.<Service>/<Method>. In v5 the prefix was mandatory, always/twirp.
  • Error code ResourceExhausted maps to HTTP code 429. In v5 it mapped to 403.

Changes in the Go Twirp v7.0.0 release:

  • #264 Optional Twirp Prefix. Implements the proposal #263 with the optional prefix, using an option to specify a different prefix than the default value "/twirp". The default value ensures backwards compatibility when updating the service. Using different prefixes, it is now possible to mount the same Twirp service in multiple routes, which may help migrating existing services from the "/twirp" prefix to a new one.
  • #264 also introduces server options on the server constructor, that can be used to setup hooks and new options like the path prefix.
  • #270 ResourceExhausted error code changed to 429 HTTP status code. This may affect middleware if it depends on a specific status code being used.
  • #271 Server JSON responses using EmitDefaults: responses include all fields, even if they have zero-values. This can be reverted to the previous behavior (skip zero-values) with the server option: twirp.WithServerJSONSkipDefaults(true).
  • #257 Go services handle literal routes. Fixing part of the issue #244, affecting cross-language communications when the proto definitions are not using the recommended Protobuf Style Guide.
  • #268 Bufgfix: Allow to update context from server Error hooks, so they can communicate with the ResponseSent hook if needed.

Go Upgrade instructions

For the most part, the upgrade to the new version should work out of the box. But there are a few areas to pay attention, depending if your service is using some specific features or not.

Twirp has two components, the twirp package and the code generator plugin (protoc-gen-twirp). One thing is to upgrade the package to the latest version, and another thing is to re-generate the server/client code with the latest version. You should upgrade the package first, because it works with older generated clients.

Upgrade the twirp package to version v7.0.0 in your project.

  • If you are explicitly using twirp.ServerHTTPStatusFromErrorCode(twirp.ResourceExhausted), the returned value will change from 403 to 429.
  • If your service is returning errors with the code twirp.ResourceExhausted and you have middleware and/or monitoring tools that depend on the HTTP status code, they will now see a change from 403 to 429.

Generate code with version v7+ of the plugin protoc-gen-twirp.

  • If your service is serving JSON requests under heavy traffic requirements, make sure to skip defaults with the option twirp.WithServerJSONSkipDefaults(true). Pass this option as an extra argument to the New<Service>Server constructor. See more details on #271

Importing Twirp clients from other services:

  • If your service is importing Twirp clients from other services that were generated in older versions, don't worry, they still work.
  • The new v7 package works for clients that were generated with the older v5 generator.
  • But the new v7 clients require the new v7 package to compile.
  • If you have multiple services that depend on each other, update the twirp package on all services first. Don't re-generate the code yet. Once all services have the v7 package, you can update the protoc-gen-twirp to v7 and re-generate all clients.

v5.12.1

3 years ago

This release fixes an issue in the generated Go client code where the request context is not properly passed to the ResponseReceived client hook.