A simple RPC framework with protobuf service definitions
Full Changelog: https://github.com/twitchtv/twirp/compare/v8.1.2...v8.1.3
Full Changelog: https://github.com/twitchtv/twirp/compare/v8.1.1...v8.1.2
protoc
from returning an error when the option is used with twirp. No change to the generated code or runtime library was necessary.
error
when closing the response Body, PR-336. This works around an upstream issue in Go 1.16.10 and Go 1.17.3.code.Error(msg)
and code.Errorf(msg, a...)
. PR-339
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.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.1.13+
is needed for the errors package Is/As/Unwrap functions.v8.1.0
.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.
PR #304: Twirp v8 generates code that depends on Protobuf APIv2 (instead of APIv1).
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:
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
.go install github.com/twitchtv/twirp/protoc-gen-twirp@latest
.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:
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
reflect.DeepEqual
will not be able to compare protobuf, you can use proto.Equal instead.context.Canceled
and context.DeadlineExceeded
during body read error, and returning meaningful error 4XX instead of a 5XX error.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.
<prefix>/<package>.<Service>/<Method>
. In v5 the prefix was mandatory, always/twirp
.ResourceExhausted
maps to HTTP code 429
. In v5 it mapped to 403
.twirp.WithServerJSONSkipDefaults(true)
.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.
twirp.ServerHTTPStatusFromErrorCode(twirp.ResourceExhausted)
, the returned value will change from 403
to 429
.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
.
twirp.WithServerJSONSkipDefaults(true)
. Pass this option as an extra argument to the New<Service>Server
constructor. See more details on #271Importing Twirp clients from other services:
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.This release fixes an issue in the generated Go client code where the request context is not properly passed to the ResponseReceived client hook.