JSPM

  • Created
  • Published
  • Downloads 45710
  • Score
    100M100P100Q152738F
  • License MIT

Autogenerate Twirp Clients and Servers in TypeScript

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.

Installation 📦

  1. Install the protocol buffers compiler:
    • brew install protobuf
  2. Add this package to your project:
    • yarn add twirpscript

Getting Started

Overview 📖

To make a Twirp service:

  1. Define your service in a .proto file.
  2. Run yarn twirpscript to generate TypeScript code from your .proto file. This will generate a service interface, client, and server utilities.
  3. Implement the generated service interface to build your service.
  4. Attach your implemented service to your application server.

1. Define your service

Create a proto specification file:

src/server/haberdasher/service.proto

syntax = "proto3";

package twirp.example.haberdasher;

// 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 service.pb.ts in the same directory as as service.proto.

3. Implement the generated service interface to build your service.

src/haberdasher/index.ts

import { Haberdasher, HaberdasherHandler } from "./service.pb";

export const HaberdasherService: Haberdasher = {
  MakeHat: (size) => {
    return {
      inches: size.inches,
      color: "red",
      name: "fedora",
    };
  },
};

export const HaberdasherServiceHandler = HaberdasherHandler(HaberdasherService);

4. Attach your implemented service to your application server.

src/server/index.ts

import { createServer } from "http";
import { createServerHandler } from "twirpscript";
import { HaberdasherServiceHandler } from "./haberdasher";

const PORT = 8080;

const twirpHandler = createServerHandler([HaberdasherServiceHandler]);
const server = createServer(twirpHandler);

server.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/service.pb";

const size = { inches: 12 };
const hat = await MakeHat("http://localhost:8080", size);
console.log(hat);

Examples 🚀

Checkout out a fullstack example of a browser client and server implementation.

FAQ

What about middleware? Does this work with Express?

Yes, the server implementation can be plugged into any connect framework. See the connect example for an example implementation.

Compatibility 🛠

The default clients use fetch so your runtime must include fetch.

Contributing 👫

PR's and issues welcomed! For more guidance check out CONTRIBUTING.md

Licensing 📃

See the project's MIT License.