• Stars
    star
    140
  • Rank 261,473 (Top 6 %)
  • Language
    Go
  • License
    Other
  • Created about 9 years ago
  • Updated 6 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Thrift improved

Frugal

Build Status

Frugal is an extension of Apache Thrift which provides additional functionality. Key features include:

  • request headers
  • request multiplexing
  • request interceptors
  • per-request timeouts
  • thread-safe clients
  • code-generated pub/sub APIs
  • support for Go, Java, Dart, and Python (2.7 and 3.5)

Frugal is intended to act as a superset of Thrift, meaning it implements the same functionality as Thrift with some additional features. For a more detailed explanation, see the documentation.

Installation

Homebrew

brew install frugal

Download

Pre-compiled binaries for OS X and Linux are available from the Github releases tab. Currently, adding these binaries is a manual process. If a downloadable release is missing, notify the messaging team to have it added.

If go is already installed and setup you can also simply:

$ go get github.com/Workiva/frugal

From Source

If go is already installed and setup, you can run the following commands:

$ git clone [email protected]:Workiva/frugal.git
$ cd frugal
$ go install

When generating go, be aware the frugal go library and the frugal compiler have separate dependencies.

Usage

Define your Frugal file which contains your pub/sub interface, or scopes, and Thrift definitions.

# event.frugal

// Anything allowed in a .thrift file is allowed in a .frugal file.
struct Event {
    1: i64 ID,
    2: string Message
}

// Scopes are a Frugal extension for pub/sub APIs.
scope Events {
    EventCreated: Event
}

Generate the code with frugal. Currently, only Go, Java, Dart, and Python are supported.

$ frugal -gen=go event.frugal

By default, generated code is placed in a gen-* directory. This code can then be used in your application. Example code is avaliable in the examples/ directory for supported languages.

Prefixes

By default, Frugal publishes messages on the topic <scope>.<operation>. For example, the EventCreated operation in the following Frugal definition would be published on Events.EventCreated:

scope Events {
    EventCreated: Event
}

Custom topic prefixes can be defined on a per-scope basis:

scope Events prefix foo.bar {
    EventCreated: Event
}

As a result, EventCreated would be published on foo.bar.Events.EventCreated.

Prefixes can also define variables which are provided at publish and subscribe time:

scope Events prefix foo.{user} {
    EventCreated: Event
}

This variable is then passed to publish and subscribe calls:

var (
    event = &event.Event{ID: 42, Message: "hello, world!"}
    user  = "bill"
)
publisher.PublishEventCreated(frugal.NewFContext(""), event, user)

subscriber.SubscribeEventCreated(user, func(ctx *frugal.FContext, e *event.Event) {
    fmt.Printf("Received event for %s: %s\n", user, e.Message)
})

Generated Comments

In Thrift, comments of the form /** ... */ are included in generated code. In Frugal, to include comments in generated code, they should be of the form /**@ ... */.

/**@
 * This comment is included in the generated code because
 * it has the @ sign.
 */
struct Foo {}

/**@ This comment is included too. */
service FooService {
    /** This comment isn't included because it doesn't have the @ sign. */
    Foo getFoo()
}

Annotations

Annotations are extra directive in the IDL that can alter the way code is generated. Some common annotations are listed below

Annotation Values Allowed Places Description
vendor Optional location Namespaces, Includes See vendoring includes
deprecated Optional description Service methods, Struct/union/exception fields See deprecating

Vendoring Includes

Frugal does not generate code for includes by default. The -r flag is required to recursively generate includes. If -r is set, Frugal generates the entire IDL tree, including code for includes, in the same output directory (as specified by -out) by default. Since this can cause problems when using a library that uses a Frugal-generated object generated with the same IDL in two or more places, Frugal provides special support for vendoring dependencies through a vendor annotation on includes and namespaces.

The vendor annotation is used on namespace definitions to indicate to any consumers of the IDL where the generated code is vendored so that consumers can generate code that points to it. This cannot be used with * namespaces since it is language-dependent. Consumers then use the vendor annotation on includes they wish to vendor. The value provided on the include-side vendor annotation, if any, is ignored.

When an include is annotated with vendor, Frugal will skip generating the include if use_vendor language option is set since this flag indicates intention to use the vendored code as advertised by the vendor annotation.

If no location is specified by the vendor annotation, the behavior is defined by the language generator.

The vendor annotation is currently only supported by Go, Dart and Java.

The example below illustrates how this works.

bar.frugal ("providing" IDL):

namespace go bar (vendor="github.com/Workiva/my-repo/gen-go/bar")
namespace dart bar (vendor="my-repo/gen-go")
namespace java bar (vendor="com.workiva.bar.custom.pkg")

struct Struct {}

foo.frugal ("consuming" IDL):

include "bar.frugal" (vendor)

service MyService {
    bar.Struct getStruct()
}
frugal -r -gen go:package_prefix=github.com/Workiva/my-other-repo/gen-go,use_vendor foo.frugal

When we run the above command to generate foo.frugal, Frugal will not generate code for bar.frugal since use_vendor is set and the "providing" IDL has a vendor path set for the Go namespace. Instead, the generated code for foo.frugal will reference the vendor path specified in bar.frugal (github.com/Workiva/my-repo/gen-go/bar).

Deprecating

Marks a method or field as deprecated (if supported by the language, or in a comment otherwise), and logs a warning if a deprecated method is called. This is not available on an entire struct, only the fields within the struct.

  Struct GetFooRequest {
      1: String value (deprecated="Use newValue instead")
  }

  GetFooResponse getFoo(10: GetFooRequest request) throws (
    1: FooError error
  ) (deprecated="Use getBar instead")

In Dart, this compiles to

class GetFooRequest implements thrift.TBase {
  ...

  /// Deprecated: Use newValue instead
  @deprecated
  List<String> _value;
  ...
}
  /// Deprecated: Use getBar instead
  @deprecated
  Future<namespace.GetFooResponse> getFoo(frugal.FContext ctx, namespace.GetFooRequest request);

Thrift Parity

Frugal is intended to be a superset of Thrift, meaning valid Thrift should be valid Frugal. File an issue if you discover an inconsistency in compatibility with the IDL.

More Repositories

1

go-datastructures

A collection of useful, performant, and threadsafe Go datastructures.
Go
7,607
star
2

eva

A distributed database-system implementing an entity-attribute-value data-model that is time-aware, accumulative, and atomically consistent
Clojure
564
star
3

over_react

A library for building statically-typed React UI components using Dart.
Dart
427
star
4

react-dart

Dart Bindings for React JS
JavaScript
412
star
5

built_redux

an implementation of redux written in dart that enforces immutability
Dart
125
star
6

dart_dev

Centralized tooling for Dart projects. Consistent interface across projects. Easily configurable.
Dart
75
star
7

dart_codemod

A library that makes it easy to write and run automated code modifications on a codebase.
Dart
60
star
8

state_machine

Easily create a finite state machine and define legal state transitions. Listen to state entrances, departures, and transitions.
Dart
60
star
9

opentelemetry-dart

Dart
57
star
10

dependency_validator

A tool to help you find missing, under-promoted, over-promoted, and unused dependencies.
Dart
56
star
11

go-rest

A Go library that makes it easy to build a flexible and (mostly) unopinionated REST API with little ceremony.
Go
49
star
12

furious

Fast and modular async task library for Google App Engine.
Python
37
star
13

w_flux

A Dart app architecture library with uni-directional data flow inspired by RefluxJS and Facebook's Flux.
Dart
25
star
14

morphe

A Clojure utility for defining and applying aspects to function definitions.
Clojure
25
star
15

w_transport

A platform-agnostic transport library for sending and receiving data over HTTP and WebSocket.
Dart
22
star
16

aws-lambda-fsm-workflows

A Python framework for developing finite state machine-based workflows on AWS Lambda.
Python
21
star
17

dart_to_js_script_rewriter

A pub transformer that Rewrites Dart script tags to JavaScript script tags, eliminating 404s and speeding up initial loads. Use when building for deployment.
Dart
21
star
18

w_module

Base module classes with a well defined lifecycle for modular Dart applications.
Dart
19
star
19

platform_detect

A library for detecting browser and platform type and version.
Dart
19
star
20

go-hystrimp

An ergonomic implementation of Hystrix fault-tolerance principles for Go developers.
Go
19
star
21

fluri

Fluri is a fluent URI library for Dart built to make URI mutation easy.
Dart
18
star
22

gae-financials

Simple demo app to illustrate developing real world applications on Google App Engine.
Python
18
star
23

thrift-nats

A library that adds support for using NATS as a Thrift RPC transport.
Go
14
star
24

wf-uicomponents

Mobile-optimized, composable UI components that support a rich HTML5 user experience.
JavaScript
13
star
25

wGulp

Opinionated Suite of Gulp Tasks for JavaScript and TypeScript projects.
JavaScript
12
star
26

scip-dart

Dart
11
star
27

utiliva

A collection of helpful little utilities for Clojure.
Clojure
11
star
28

webdev_proxy

A simple HTTP proxy for the webdev serve command (a tool authored by the dart team) that adds support for rewriting certain requests, namely rewriting 404s to instead serve the root index (/index.html). This allows developers to work on browser applications (like our own) that use HTML5 routing while still being able to refresh and/or navigate directly to deep links.
JavaScript
11
star
29

r_tree

A recursive RTree library written in Dart.
Dart
10
star
30

opentracing_dart

This library is the Open Tracing API written in Dart. It is intended for use both on the server and in the browser.
Dart
10
star
31

w_common

A collection of helpful utilities for use in Dart projects.
Dart
10
star
32

styleguide

9
star
33

pdfjs_dart

Dart bindings for Mozilla's PDF.js library
JavaScript
7
star
34

flowgraph

A Clojure library for fast, concurrent, asynchronous data processing using directed graphs. Decursus supports cyclic graphs. Though it is not distributed, it does have primitive tools for minimizing communication overhead in the event that some processing steps involve calls to distributed resources.
Clojure
6
star
35

wf-common

A collection of helpful utilities for use in JavaScript projects.
JavaScript
6
star
36

over_react_test

A library for testing OverReact components
Dart
6
star
37

dart_transformer_utils

Utilities relating to code generation, Dart analyzer, logging, etc. for use in Pub transformers.
Dart
6
star
38

w_service

Dart
5
star
39

react_testing_library

Dart bindings for the JS dom-testing-library and react-testing-library packages, which provide simple and complete DOM/React testing utilities that encourage good testing practices.
Dart
5
star
40

tesserae

A Clojure library that abstracts over promises, futures, delays, etc. with chaining and cancellations.
Clojure
4
star
41

w-mobile-kit

A Swift library containing various custom UI components to provide functionality outside of the default libraries.
Swift
4
star
42

wf-grunt

Opinionated Suite of Grunt Tasks for JavaScript and TypeScript projects.
JavaScript
4
star
43

goverge

A golang multi package coverage reporting tool.
Python
3
star
44

autoPaw

JavaScript
3
star
45

paw

A touch / touch gesture simulation library for JavaScript.
JavaScript
3
star
46

sockjs-dart-client

A Dart client library for SockJS.
Dart
3
star
47

workiva_analysis_options

Workiva's shared Dart static analysis options
Dart
3
star
48

lsif_indexer

Dart
2
star
49

eva-client-service

The Eva client service is an Eva peer which exposes Eva functionality to other languages through a REST interface.
Java
2
star
50

over_react_codemod

Codemods to help consumers of over_react automate the migration of UI component code.
Dart
2
star
51

font_face_observer

Load and unload fonts in the browser with a Promise based API. Simple, small and efficient. It will use the FontFace api if available, otherwise it falls back to a Dart port of https://github.com/bramstein/fontfaceobserver
Dart
2
star
52

sockjs_client_wrapper

A Dart wrapper around the SockJS Client. Uses the js Dart package to interop with the JS lib.
JavaScript
2
star
53

eva-catalog

Provides a central repository (and client) for handling the configuration maps used to connect to EVA
Clojure
1
star
54

lazy-tables

A set of tools for lazy relational algebra
Clojure
1
star
55

test_html_builder

Dart builder that generates HTML files from templates for dart tests.
Dart
1
star
56

abide

A command line tool to manage analysis_options.yaml and check if it abides by requirements.
Dart
1
star
57

barometer

A thin clojure wrapper over Coda Hale's metrics library for the JVM.
Clojure
1
star
58

ichnaie

A handful of Clojure utilities for easing project integration with the OpenTracing API
Clojure
1
star
59

recide

Provides utilities for defining standard ex-info forms, as well as the capacity for checking at compile-time that they are being used as intended
Clojure
1
star
60

dpx

Dart
1
star