Skip to content

helsing-ai/twurst

Repository files navigation

Twurst

Twurst is an implementation of Twirp v7 in Rust on top of prost, the tower ecosystem and axum. It fully supports JSON and its server can also serve regular gRPC.

What is Twirp?

Twirp is a protocol similar to gRPC but with some differences:

  • Based on protobuf and gRPC service definitions
  • Uses plain HTTP 1.1 as a wire format (with upgrade to HTTP 2/3 if the client and server agree)
  • No stream requests/responses
  • Protobuf JSON format is a first class citizen and can be used instead of protobuf binary encoding
  • Errors are encoded as a JSON payload and correct HTTP status code must be used

Useful properties:

  • Same protocol level behaviors as web browsers and tools like curl or reqwest just work
  • JSON if text based human-readable communications are required
  • Same definition files as gRPC, fairly simple migration coming from gRPC

Twirp has been created by Twitch and its original implementation is in Go. A list of other implementations is provided.

This implementation

This is a simple implementation of Twirp. Its aim is to be a replacement of tonic using Twirp instead of gRPC. It is also based on prost with the help of prost-reflect for JSON support.

It is split into multiple crates:

  • twurst-build is the equivalent of tonic-build for Twirp: it generates code from the .proto files.
  • twurst-client wraps a reqwest::Client or any tower::Service and provides the needed code for the *Client structs generated by twurst-build to work.
  • twurst-server implements a Twirp server on top of axum from an implementation of the service trait generated by twurst-build. It is not a fully fledged server but only an axum::Router that can be integrated into a bigger HTTP server (remind, Twirp uses regular HTTP(S)).
  • twurst-error provides the TwirpError type (think tonic::Status but for Twirp). It is reexported by the other crates, and you should not need to depend on it directly.

Client and server examples are provided in the example directory. example/js-client provides an example of a naive JS client.

Support for gRPC is also provided behind the grpc feature in twurst-build and twurst-server. It allows to easily serve both Twirp and gRPC. example/server provides an example.

For more detailed documentation see the client and the server READMEs.

Getting started

  1. Read the example/client and example/server directories.
  2. Copy/paste and adapt the code if you want to build a server or a client.
  3. Read the client and/or the server READMEs for more documentation.

Differences with other Twirp implementations

  • prost_twirp does not support JSON, Twirp 7 and last commit was on January 2023.
  • twirp-rs does not allow any Tower Service in the client, has a more restricted JSON support based on prost-wkt and not on prost-reflect leading to eg. troubles with oneOf support or does not support custom fields based on Axum extractors added to the server generated methods.

License

Copyright 2024 Helsing GmbH

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.