17

GitHub - evinism/buttery: Minimalistic language for defining HTTP(s) and Websock...

 3 years ago
source link: https://github.com/evinism/buttery
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Buttery: Minimalistic language for defining HTTP(s) APIs

Warning: Buttery is still in alpha and is not (yet) suitable for production use. It CAN be used for side projects and game jams.

Buttery aims to be a minimalistic cross-platform language for defining type-safe RPCs and websockets. Buttery provides codegen and runtimes for browsers and node.js, with the intent of expanding to other platforms.

Example

Let's say we're building a basic chat app over websockets.

We define the interface in a .butt (or alternatively .buttery) file:

# chat.butt
service ChatService:
  struct SendMessage:
    timestamp: integer
    content: string

  struct NewMessageUpdate:
    timestamp: integer
    author: string
    content: string

  channel Chat:
    incoming: SendMessage
    outgoing: NewMessageUpdate

We generate a client and server via the cli:

$ buttery generate browser -f chat.butt
 [ ... ]
$ buttery generate node -f chat.butt
 [ ... ]

And consume the generated files in a sample client and server:

// client.ts on the frontend
import { ChatService } from "./buttery-genfiles/chat.browser";

const client = new ChatService("https://example.com");
const chatConnection = client.Chat();

chatConnection.listen((msg) => {
  console.log(msg.content);
});

chatConnection.send({ timestamp: Date.now(), content: "Hello, world!" });
// server.ts on the backend
import {ButteryServer} from 'buttery-node';
import {ChatService} from './buttery-genfiles/chat.node'

const butteryServer = new ButteryServer();
butteryServer.implement(ChatService, "Chat", (connection) => {
  connection.listen(msg => {
    connection.send({
      timetamp: Date.now(),
      author: "Server"
      content: 'Thanks for sending me a message!'
    });
  });
});
butteryServer.createServer().listen(8080);

Installation:

Installation via npm, e.g. npm install -g buttery-cli

Buttery's CLI is very simple right now:

buttery generate <target environment> -f [files]

As an example call:

buttery generate browser -f ./path/to/file.butt

By default, this creates generated files in the buttery-genfiles directory. This can be changed via the -o [path] parameter. It's probably a good idea to gitignore that directory.

Buttery Target Support

Buttery Clients

Target Target Description Support
browser Generated Typescript for use in browsers Full Support
python-client Generated code for Python Client None

Buttery Servers

Target Target Description Support
node Generated Typescript for use in express backends Full Support
django Generated code for use in Django backends None

Scope of Buttery

Buttery aims to provide:

  1. A lightweight language for defining over-the-network APIs.
  2. First-class support for full duplex communication.
  3. Codegen for clients and servers in a variety of languages.
  4. Parsing and validation of requests and responses.
  5. (when applicable) Cross-language, cross network boundary type safety.
  6. Basic reliability abstractions, such as retries and message buffers for 2-way connections

Buttery does not aim to provide:

  1. Strong protections against version skew of specific definitions.
  2. Highly size-optimized over-the-wire encodings -- Buttery messages are valid JSON
  3. Support for non-evergreen browsers

Sample patterns of places where Buttery could be used:

  • Backend to backend RPCs
  • Frontend requests to backend services
  • As a wrapper around websockets for server push
  • Easy multiplexing of multiple services through a single host

Comparison to other solutions

Depending on your background, you might find one of these comparisons useful:

  • A lightweight replacement for gRPC / protos, but over http(s) and websockets
  • Twirp, but without all the baggage of protos, providing first-class support for browser -> backend comms, and bidi communication
  • A lightweight replacement for swagger codegen, with bidi communication
  • JSON-RPC-like specification, but paired with a small domain specific language for definitions and bidi communication

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK