Package Exports
- twirpscript
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (twirpscript) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
TwirpScript
Autogenerate Twirp Clients and Servers in TypeScript
What is this? 🧐
TwirpScript is an implementation of the Twirp wire protocol for TypeScript. It generates idiomatic TypeScript clients and servers from .proto service specifications. The generated clients can be used in the browser. This enables type safe communication between the client and server for web applications, as well as reduced payload sizes when using protobuf as the serialization format.
Twirp is a simple RPC framework built on protocol buffers. You define a service in a .proto specification file, and Twirp will generate servers and clients for that service. You fill in the business logic that powers the server, and Twirp handles the boilerplate. In addition to abstracting away boilerplate, this provides type safe interactions between the client and the server.
To learn more about the motivation behind Twirp (and a comparison to REST APIs and gRPC), check out the announcement blog.
Features 🛠
- One runtime dependency: Google's protobuf js for protobuf serialization / deserialization.
- A custom TypeScript plugin for
protocthat generates idiomatic JavaScript interfaces. None of the Java idioms thatprotoc --js_outgenerates like the{$field}Listnaming for repeated fields or the various getter / setter methods. The TwirpScript plugin uses plain JavaScript objects over classes. - Comments in
protofiles become TSDoc comments that will show documentation inline in supported editors. - Isomorphic clients that work server side* and are also optimized for the browser. The clients are built with tree shaking in mind. You you can drop the one runtime dependency,
protobuf js, when using only the generated JSON clients and a bundler that supports tree shaking.
* Requires that the runtime provides fetch. See Compatibility for more details.
Installation 📦
Install the protocol buffers compiler:
brew install protobuf(MacOS. See other installation options)Add this package to your project:
yarn add twirpscript
Getting Started
Overview 📖
To make a Twirp service:
- Define your service in a
.protofile. - Run
yarn twirpscriptto generate TypeScript code from your.protofile. This will generate JSON and Protobuf clients, a service interface, and server utilities. - Implement the generated service interface to build your service.
- Attach your implemented service to your application server.
- Use the generated client to make requests to your server.
1. Define your service
Create a proto specification file:
src/server/haberdasher/haberdasher.proto
syntax = "proto3";
// Haberdasher service makes hats for clients.
service Haberdasher {
// MakeHat produces a hat of mysterious, randomly-selected color!
rpc MakeHat(Size) returns (Hat);
}
// Size of a Hat, in inches.
message Size {
int32 inches = 1; // must be > 0
}
// A Hat is a piece of headwear made by a Haberdasher.
message Hat {
int32 inches = 1;
string color = 2; // anything but "invisible"
string name = 3; // i.e. "bowler"
}2. Run yarn twirpscript
This will generate haberdasher.pb.ts in the same directory as as haberdasher.proto. Any comments will become TSDoc comments and will show inline in supported editors.
yarn twirpscript will compile all.proto files in your project.
3. Implement the generated service interface to build your service.
src/server/haberdasher/index.ts
import { HaberdasherService, createHaberdasherHandler } from "./service.pb";
const Haberdasher: HaberdasherService = {
MakeHat: (size) => {
return {
inches: size.inches,
color: "red",
name: "fedora",
};
},
};
export const HaberdasherHandler = createHaberdasherHandler(HaberdasherService);4. Attach your implemented service to your application server.
src/server/index.ts
import { createServer } from "http";
import { createTwirpServer } from "twirpscript";
import { HaberdasherHandler } from "./haberdasher";
const PORT = 8080;
const app = createTwirpServer([HaberdasherHandler]);
createServer(app).listen(PORT, () =>
console.log(`Server listening on port ${PORT}`)
);5. Client
That's it for the server! Now you can use the generated clients to make json or protobuf requests to your server:
src/client.ts
import { MakeHat } from "./server/haberdasher/haberdasher.pb";
const hat = await MakeHat("http://localhost:8080", { inches: 12 });
console.log(hat);Connecting to an existing Twirp server and only need a TypeScript client?
- Get your service
.protofile. - Run
yarn twirpscriptto generate TypeScript code from your.protofile. - Use the generated client to make requests to your server.
Examples 🚀
The documentation is a work in progress. Checkout the examples in the examples directory:
- The fullstack example shows a minimal browser client and server implementation.
- The authentication example extends the fullstack example to demonstrate authentication using tokens.
The examples also include testing via jest.
Compatibility 🛠
The default clients use fetch so your runtime must include fetch. See an example from the clientcompat test example.
Contributing 👫
PR's and issues welcomed! For more guidance check out CONTRIBUTING.md
Licensing 📃
See the project's MIT License.