Releases: twitchtv/twirp
v8.1.3
What's Changed
- Fix spelling error by @delaneyj in #357
- Fix spelling by @delaneyj in #358
- Add link to crystal implementation by @mloughran in #360
- Replace references to Error type with Error code by @davidblnc in #363
- Remove deprecated ioutil from generator by @marwan-at-work in #367
- Update docs for Twirp Errors by @marioizquierdo in #368 and #369
New Contributors
- @delaneyj made their first contribution in #357
- @mloughran made their first contribution in #360
- @davidblnc made their first contribution in #363
Full Changelog: v8.1.2...v8.1.3
v8.1.2
What's Changed
- Add timostamm/protobuf-ts to implementations by @QuantumGhost in #344
- Make README third-party table consistent by @nihaals in #345
- Docs to migrate REST APIs to Twirp by @marioizquierdo in #347
- Fix generation of the best practices page by @hugosrc in #349
- Fix generated file name error in some cases by @albenik in #351
New Contributors
- @QuantumGhost made their first contribution in #344
- @nihaals made their first contribution in #345
- @hugosrc made their first contribution in #349
- @albenik made their first contribution in #351
Full Changelog: v8.1.1...v8.1.2
v8.1.1
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)
andcode.Errorf(msg, a...)
. PR-339 - Several minor doc changes: PR 340, PR-343, PR 341
v8.1.0
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 thetwirp.Error
interface, but also if they wrap another Twirp error, or if theyimplement the methodAs(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 belowerCamelCase
by default. If thejson_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: Protobuf APIv2
PR #304: Twirp v8 generates code that depends on Protobuf APIv2 (instead of APIv1).
Relevant links
- Protobuf APIv1 repo: https://github.com/golang/protobuf
- Protobuf APIv2 repo: https://github.com/protocolbuffers/protobuf-go
- Protobuf APIv2 release blog post: https://blog.golang.org/protobuf-apiv2
- Twirp version compatibility matrix: https://twitchtv.github.io/twirp/docs/version_matrix.html
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 optionspaths=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: Bugfix for checking context errors during body read error
- PR #294: handling and returning valid error code for
context.Canceled
andcontext.DeadlineExceeded
during body read error, and returning meaningful error 4XX instead of a 5XX error.
v7.1.1: Bugfix for go_option that contains both path and pkg
v7.1.0: Interceptors and literal routes
- 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
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 code429
. In v5 it mapped to403
.
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 from403
to429
. - 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 from403
to429
.
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 theNew<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 theprotoc-gen-twirp
to v7 and re-generate all clients.
v5.12.1: Fix client hook context bug
This release fixes an issue in the generated Go client code where the request context is not properly passed to the ResponseReceived client hook.