An OCaml client for Riak

Project maintained by metadave Hosted on GitHub Pages — Theme by mattgraham


© 2012 - 2013 Dave Parfitt

riak-ocaml-client is a Riak Protobuffs-only client for OCaml.


Building from source

make install

# To test, run this:
./configure --enable-tests
make test

Note: Testing requires a running instance of Riak 1.2+. By default, it tries to connect to Riak on, port 8081. To override these values, simply export the following two environment variables:

Installing via OPAM

opam install riak

This will also install the riak-pb dependency


Hello world

The following program makes a connection to Riak and sends a ping message.

open Riak
open Sys
open Lwt
open Lwt_unix

let test_ping conn =
  match_lwt riak_ping conn with
    | true ->
        print_endline "Pong";
        return ()
    | false ->
        return ()

let _ =
  run (
    let pbip = 10017 in
      lwt conn = riak_connect_with_defaults "" pbip in
      lwt _result = test_ping conn in
      riak_disconnect conn;
    with Unix.Unix_error (e, _, _) ->
      print_endline "Pang";
      return ()

Note: Change the IP/port to the value defined in the Riak app.config pb_port and pb_ip.

Note: The default protobuffs port in Riak 1.3 may change.

Development Guide

A note on types

Throughout the docs, you will find the following types. Almost all are strings:

type riak_bucket = string
type riak_key = string
type riak_client_id = string
type riak_mr_query = string
type riak_mr_content_type = Riak_MR_Json | Riak_MR_Erlang
type riak_2i_name = string
type riak_2i_range_min = string
type riak_2i_range_max = string
type riak_search_query = string
type riak_search_index = string
type riak_node_id = string
type riak_version = string
type riak_vclock = string

See ./src/Riak.mli for the complete interface.


val riak_connection_defaults : riak_connection_options

val riak_connect_with_defaults : string -> int -> riak_connection Lwt.t

val riak_connect : string -> int -> riak_connection_options -> riak_connection Lwt.t

val riak_disconnect : riak_connection -> unit Lwt.t

To connect using default connection properties:

    lwt conn = riak_connect_with_defaults "" 8081
Default connection properties:

The following defaults are used when calling riak_connect_with_defaults.

To override these values:

    let options = 
        { riak_connection_defaults with riak_conn_retries=5 } in
    lwt conn = riak_connect "" 8081 options in

To disconnect:

riak_disconnect conn


    val riak_ping : riak_connection -> bool Lwt.t


    match_lwt riak_ping conn with
        | true -> return ()
        | false -> assert_failure("Can't connect to Riak")

Client ID

val riak_get_client_id : riak_connection -> riak_client_id Lwt.t

val riak_set_client_id : riak_connection -> riak_client_id -> unit Lwt.t


    let test_client_id = "foo" in
    lwt _ = riak_set_client_id conn test_client_id in
    lwt client_id = riak_get_client_id conn in

Server Info

val riak_get_server_info : riak_connection -> (riak_node_id * riak_version) Lwt.t


    lwt (node, version) = riak_get_server_info conn in


val riak_get :
  riak_connection -> 
  riak_bucket -> 
  riak_key -> 
  riak_get_option list -> 
  riak_object option Lwt.t


lwt result = riak_get conn "my_bucket" "my_key" [Get_basic_quorum false; Get_head true] in

type riak_get_option =


val riak_put :
  riak_connection ->
  riak_bucket ->
  riak_key option ->
  ?links:Riak_kv_piqi.rpb_link list ->
  ?usermeta:Riak_piqi.rpb_pair list ->
  string ->
  riak_put_option list -> riak_object option Lwt.t

val riak_put_raw :
  riak_connection ->
  riak_bucket ->
  riak_key option ->
  ?links:Riak_kv_piqi.rpb_link list ->
  ?usermeta:Riak_piqi.rpb_pair list ->
  string ->
  riak_put_option list -> riak_vclock option -> riak_object option Lwt.t

If you plan on inserting new key/values, use riak_put_raw. If you aren't sure if your key/value is new, use riak_put. riak_put will try and fetch the vclock before updating to limit sibling explosion.


 let newkey = "foo" in
 let newval = "bar" in
 lwt objs = riak_put conn bucket (Some newkey) newval [Put_return_body true]
 let newkey = "foo" in
 let newval = "bar" in
 let existing_vclock = (*Some vclock *)
 lwt objs = riak_put_raw conn bucket (Some newkey) newval [Put_return_body true] existing_vclock

type riak_put_option =


val riak_del :
  riak_connection ->
  riak_bucket ->
  riak_key -> riak_del_option list -> unit Lwt.t


    lwt _ = riak_del conn bucket "del_test" [] in

type riak_del_option =

Tunable CAP Options

type riak_tunable_cap =

List Buckets

Listing buckets is not recommended in a production environment

val riak_list_buckets : riak_connection -> riak_bucket list Lwt.t


 lwt buckets = riak_list_buckets conn in

List Keys

Listing keys is not recommended in a production environment

val riak_list_keys : riak_connection -> riak_bucket -> riak_key list Lwt.t


 lwt keys = riak_list_keys conn "mybucket" in

Get Bucket Props (limited)

At the moment, Riak Protobuffs only implement 2 bucket properties,

val riak_get_bucket : 
    riak_connection -> 
    riak_bucket -> 
    (int32 option * bool option) Lwt.t


 lwt (n, multi) = riak_get_bucket conn bucket in
      (match n with
        | Some nval -> assert_bool "Valid bucket n value" (nval > 0l)
        | None -> assert_failure "Unexpected default N value");
      (match multi with
        | Some multival -> assert_equal false multival
        | None -> assert_failure "Unexpected default multi value")

Set Bucket Props (limited)

At the moment, Riak Protobuffs only implement 2 bucket properties,

val riak_set_bucket : 
    riak_connection -> 
    riak_bucket -> 
    int32 option -> 
    bool option -> 
    unit Lwt.t


  let n_val = 2l in
  let allow_mult = (Some true) in
  lwt _ = riak_set_bucket conn bucket n_val allow_mult in


val riak_mapred :
  riak_connection ->
  riak_mr_query ->
  riak_mr_content_type ->
  (string option * int32 option) list Lwt.t


See src/test.ml for an example.

Index Query

Secondary index (2i) exact match query:

val riak_index_eq :
  riak_connection ->
  riak_bucket ->
  riak_2i_name ->
  riak_key option -> string list Lwt.t

Secondary index (2i) range query:

val riak_index_range :
  riak_connection ->
  riak_bucket ->
  riak_2i_name ->
  riak_2i_range_min option ->
  riak_2i_range_max option -> string list Lwt.t

Riak Search

val riak_search_query :
  riak_connection ->
  string ->
  string ->
  riak_search_option list ->
  ((string * string option) list list *
  Riak_search_piqi.Riak_search_piqi.float32 option *
  Riak_search_piqi.Riak_search_piqi.uint32 option) Lwt.t

type riak_search_option =

A note on HTTP operations

As most official Riak clients will only support Protobuffs in the future, HTTP operations aren't supported in the OCaml client (and won't ever be). This does **NOT* mean that the HTTP interface for Riak is going away.*



See THANKS file for more details.


* test search, index
* better error handling
* Next version: officially test with OCaml 4

© 2012 - 2013 Dave Parfitt

Portions of the documentation are © 2012 - 2013 Basho Technologies