Skip to content
This repository has been archived by the owner. It is now read-only.
A Clojure abstraction for Thrift
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.


Build Status

A Clojure library for working with Thrift types.


Add clj-thrift to your project's dependencies. If you're using Leiningen, your project.clj should look something like this:

(defproject ...
  :dependencies [[clj-thrift VERSION]])

Where VERSION is the latest version on Clojars.

Working With Thrift Values

The examples in this README are for the following Thrift IDL:

struct Name {
  1: required string firstName;
  2: required string lastName;

union Identity {
  1: Name name;
  2: string ssn;


A Thrift object can be constructed recursively from a Clojure map with

(require '[clj-thrift.base :as thrift])

(thrift/build Name {:firstName "John" :lastName "Smith"})
; => #<Name Name(firstName:John, lastName:Smith)>

; Also works for unions:
(thrift/build Identity {:name {:firstName "John" :lastName "Smith"}})
; => #<Identity <Identity name:Name(firstName:John, lastName:Smith)>>

Reading and modifying a object's fields is supported by clj-thrift.base/value and clj-thrift.base/value!. value! returns the object being modified so that it can be threaded with ->.

(def full-name (-> (Name.)
                 (thrift/value! :firstName "John")
                 (thrift/value! :lastName "Smith")))

(thrift/value full-name :firstName)
; => "John"


Unions are like structs that can only have one field set at a time (called the current field). value! sets the union's current field. In addition, the current field's value can be queried with clj-thrift.union/current-value and it's tag number with clj-thrift.union/current-field-id:

(require '[clj-thrift.union :as union])

(def id-1 (thrift/build Identity {:name {:firstName "John" :lastName "Smith"}}))
(def id-2 (-> (Identity.)
            (thrift/value! :ssn "555-55-5555")))

(thrift/current-value id-1)
; => #<Name Name(firstName:John, lastName:Smith)>

(thrift/current-value id-2)
; => "555-55-5555"


clj-thrift provides referentially-transparent functions for serializing and deserializing Thrift objects using Thrift's native serialization classes, TSerializer and TDeserializer. clj-thrift hides the mutability that is inherent to TDeserializer so that serialization and deserialization behave like pure functions:

(require '[clj-thrift.serialization :as s])

(def buf (s/serialize (Name. "John" "Smith")))

(s/deserialize Name buf)
; => #<Name Name(firstName:John, lastName:Smith)>

Hint: serialize and deserialize can be partially applied to create type- and protocol-specific serialization functions:

(require '[clj-thrift.protocol.factory :as protocol])

(def serialize (partial s/serializer (s/serializer (protocol/compact))))
(def deserialize (partial s/deserialize (s/deserializer (protocol/compact)) Name))

(def buf (serialize (Name. "John" "Smith")))

(deserialize buf)
; => #<Name Name(firstName:John, lastName:Smith)>

Currying the serializer and deserializer can reduce load on the garbage collector.

Meta Programming

The clj-thrift.type namespace provides some functions for looking up meta-data about a Thrift type. This namespace answers questions that can be answered by inspecting a Thrift class's metaDataMap field or _Fields enum.


Copyright © 2013 David Cuddeback

Distributed under the MIT License.

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.