How to Use the Riak HTTP Interface Step 1 in using the Riak HTTP interface is to enable the Riak web interface. Add these two lines to your riak config, in the 'riak_core' section: {web_ip, "127.0.0.1"}. {web_port, 8098}. Now start Riak with your config file, and you'll find the HTTP interface at http://127.0.0.1:8098/riak/... If you'd rather have some prefix other than "riak", add another line to your config: {raw_name, "myprefix"}. You'll find that all buckets exist, and are ready to give you details about themselves at /riak/BucketName: $ curl -i http://127.0.0.1:8098/riak/example HTTP/1.1 200 OK Vary: Accept-Encoding Server: MochiWeb/1.1 WebMachine/1.7 (participate in the frantic) Date: Wed, 14 Jul 2010 03:28:46 GMT Content-Type: application/json Content-Length: 370 {"props":{"name":"bucket","n_val":3,"allow_mult":false,"last_write_wins":false,"precommit":[],"postcommit":[],"chash_keyfun":{"mod":"riak_core_util","fun":"chash_std_keyfun"},"linkfun":{"mod":"riak_kv_wm_link_walker","fun":"mapreduce_linkfun"},"old_vclock":86400,"young_vclock":20,"big_vclock":50,"small_vclock":10,"r":"quorum","w":"quorum","dw":"quorum","rw":"quorum"}} It is not necessary to "create" or otherwise "touch" a bucket before storing documents into it, but if you want to change a property at runtime, it's as simple as PUTing to the bucket: $ curl -X PUT -H "content-type: application/json" \ http://127.0.0.1:8098/riak/example --data "{\"props\":{\"n_val\":4}}" This would change the n_val of the bucket to 4. Storing data is just as easy - just PUT to the bucket and key: $ curl -X PUT -H "content-type: text/plain" \ http://127.0.0.1:8098/riak/example/foo --data "I have a document." The Riak HTTP interface requires only that you include a content-type, but no attempt to validate the content is made. You could use application/json just as easily as image/gif - it's up to you to provide the correct body. Whatever content type you include here will be the content type that Riak serves whenever a client attempts to GET this document. To get the document back, just GET the bucket and key: $ curl -i http://127.0.0.1:8098/riak/example/foo HTTP/1.1 200 OK X-Riak-Vclock: a85hYGBgzGDKBVIsLGtY2zOYEhnzWBkE12w8ypcFAA== Vary: Accept-Encoding Server: MochiWeb/1.1 WebMachine/1.7 (participate in the frantic) Link: </riak/example>; rel="up" Last-Modified: Wed, 14 Jul 2010 03:33:37 GMT Etag: 1wSftQ956ViTpGGs8dKQ68 Date: Wed, 14 Jul 2010 03:33:45 GMT Content-Type: text/plain Content-Length: 18 I have a document. You'll notice one odd-looking header in that response: X-Riak-Vclock. This is the vclock you want to provide with your next write to that object, in order to indicate the causality of your modification. For example: $ curl -X PUT -H "content-type: text/plain" \ -H "X-Riak-Vclock: a85hYGBgzGDKBVIsLGtY2zOYEhnzWBkE12w8ypcFAA==" \ http://127.0.0.1:8098/riak/example/foo \ --data "I have a modified document." This command will modify the document, which we can verify with a second GET: $ curl -i http://127.0.0.1:8098/riak/example/foo HTTP/1.1 200 OK X-Riak-Vclock: a85hYGBgymDKBVIsLGtY2zOYEhnzWBkE12w8ygcVZm8+GwwVPggSzgIA Vary: Accept-Encoding Server: MochiWeb/1.1 WebMachine/1.7 (participate in the frantic) Link: </riak/example>; rel="up" Last-Modified: Wed, 14 Jul 2010 03:36:33 GMT Etag: 59nvzTQTQ6ixb9jxASLDKS Date: Wed, 14 Jul 2010 03:36:36 GMT Content-Type: text/plain Content-Length: 27 I have a modified document. To delete a document, simply issue a DELETE request: $ curl -X DELETE http://127.0.0.1:8098/riak/example/foo You'll find that further GETs of that URL return status code 404. For each of the key-level document requests, you may also specify the query parameters 'r', 'w', 'dw', and 'rw', to tune the R (read), W (write), DW (durable write), and RW (read-write, for delete) value for that request. For instance: $ curl http://127.0.0.1:8098/riak/example/foo?r=1 Would get the "foo" document in the "example" bucket using an R-value of 1. == Advanced Topic 1: Siblings (multiple values) == Documents in Riak can have multiple, conflicting values if the 'allow_mult' property has been set to 'true' for a bucket. For example, if you issued the following: $ curl -X PUT -H "content-type: application/json" \ http://127.0.0.1:8098/riak/example \ --data "{\"props\":{\"allow_mult\":true}}" $ curl -X PUT -H "content-type: text/plain" \ http://127.0.0.1:8098/riak/example/sib --data "one thing" $ curl -X PUT -H "content-type: text/plain" \ http://127.0.0.1:8098/riak/example/sib --data "another" You will have created two siblings for the "sib" document in the "example" bucket. Riak won't know what to do with these siblings if you ask for the "sib" document, so instead it will just tell you that they're both there: $ curl -i http://127.0.0.1:8098/riak/example/sib HTTP/1.1 300 Multiple Choices X-Riak-Vclock: a85hYGBgzmDKBVIszBJiPRlMiYx5rAyzNmw8ygcVZoyuU4YKz0cIszUnMZ0/pIAskQUA Vary: Accept, Accept-Encoding Server: MochiWeb/1.1 WebMachine/1.7 (participate in the frantic) Date: Wed, 14 Jul 2010 03:53:08 GMT Content-Type: text/plain Content-Length: 55 Siblings: xKntdvwv9b1sIj1LArbox 3QApcpvLPS1FyKu8IrN1sV The strings listed in the body are the vtags of each sibling. To examine each sibling, perform the same GET, but add a "vtag" query parameter to the URL: $ curl http://127.0.0.1:8098/riak/example/sib?vtag=xKntdvwv9b1sIj1LArbox one thing $ curl http://127.0.0.1:8098/riak/example/sib?vtag=3QApcpvLPS1FyKu8IrN1sV another If you'd rather see all of the siblings at once, set your Accept header to multipart/mixed. Riak will hand back each of the versions as a separate part of a multipart/mixed document: $ curl -i -H "accept: multipart/mixed" http://127.0.0.1:8098/riak/example/sib HTTP/1.1 300 Multiple Choices X-Riak-Vclock: a85hYGBgzmDKBVIszBJiPRlMiYx5rAyzNmw8ygcVZoyuU4YKz0cIszUnMZ0/pIAskQUA Vary: Accept, Accept-Encoding Server: MochiWeb/1.1 WebMachine/1.7 (participate in the frantic) Date: Wed, 14 Jul 2010 03:55:24 GMT Content-Type: multipart/mixed; boundary=FOs2aRNqxNs5pyKd7eHBia2Pg7x Content-Length: 390 --FOs2aRNqxNs5pyKd7eHBia2Pg7x Content-Type: text/plain Link: </riak/example>; rel="up" Etag: xKntdvwv9b1sIj1LArbox Last-Modified: Wed, 14 Jul 2010 03:53:03 GMT another --FOs2aRNqxNs5pyKd7eHBia2Pg7x Content-Type: text/plain Link: </riak/example>; rel="up" Etag: 3QApcpvLPS1FyKu8IrN1sV Last-Modified: Wed, 14 Jul 2010 03:52:58 GMT one thing --FOs2aRNqxNs5pyKd7eHBia2Pg7x-- To resolve the conflict, just issue another PUT, with the body you want, and the vclock from this version: $ curl -X PUT -H "content-type: text/plain" \ -H "X-Riak-Vclock: a85hYGBgzmDKBVIszBJiPRlMiYx5rAyzNmw8ygcVZoyuU4YKz0cIszUnMZ0/pIAskQUA" \ http://127.0.0.1:8098/riak/example/sib --data "resolved" And you'll see that things are back to normal: $ curl http://127.0.0.1:8098/riak/example/sib resolved == Advanced Topic 2: Link walking == As with other Riak documents, you are free to specify links in your documents in any fashion you wish, as long as you also write a function for extracting them at map/reduce time. However, the HTTP interface provides a function that will handle link parsing and extraction for you, if you are able to describe your links in a Link HTTP header. Riak's Link header syntax is based on Mark Nottingham's work. You can read more about it at: http://www.mnot.net/drafts/draft-nottingham-http-link-header-00.txt For Riak, the goal is to provide a link from one document to another. For instance, you may want to link from the "jane" document in the "person" bucket to the "xyz" document in the "memo" bucket. To do this, you'd add a header of the following format to your PUT to /riak/person/jane: Link: </riak/memo/xyz>; riaktag="author" Multiple links should be separated by commas: Link: </riak/memo/xyz>; riaktag="author", </riak/memo/abc>; riaktag="reader" Performing a GET on a resource with links will return a Link header of the same format. To walk these links, use the URL-walking syntax: http://127.0.0.1:8098/riak/person/jane/memo,_,_ This request would return all of the documents in the "memo" bucket that the "jane" document links to. You could get just the "memo" documents with links tagged "author" by asking for: http://127.0.0.1:8098/riak/person/jane/memo,author,_ The response of a link walk request is always multipart/mixed content. Each part of the multipart response body is a representation of the result of the corresponding link step. That representation is also a multipart/mixed document. Each part of this inner multipart document is a representation of the Riak object that was walked to at that step. For documents with siblings, one of the siblings is chosen arbitrarily, and an X-Riak-Sibling-VTags header is added to its representation to alert the user that this is the case. A few examples are approriate: $ curl -X PUT -H "content-type: text/plain" \ http://127.0.0.1:8098/riak/memo/xyz \ --data "my reading list: New York Times, Wired" $ curl -X PUT -H "content-type: text/plain" \ http://127.0.0.1:8098/riak/memo/abc \ --data "todos: have meeting, make phone call" $ curl -X PUT -H "content-type: text/plain" \ -H "link: </riak/memo/xyz>; riaktag=\"author\", </riak/memo/abc>; riaktag=\"reader\"" \ http://127.0.0.1:8098/riak/person/jane --data "Name: Jane Doe" $ curl -i http://127.0.0.1:8098/riak/person/jane/memo,_,_ HTTP/1.1 200 OK Server: MochiWeb/1.1 WebMachine/1.7 (participate in the frantic) Expires: Wed, 14 Jul 2010 04:48:32 GMT Date: Wed, 14 Jul 2010 04:38:32 GMT Content-Type: multipart/mixed; boundary=W6v94jEJ22hI5cfwbqinnGBmwpV Content-Length: 753 --W6v94jEJ22hI5cfwbqinnGBmwpV Content-Type: multipart/mixed; boundary=SRzlI2jh68aWdVONf9n1yfDBEVx --SRzlI2jh68aWdVONf9n1yfDBEVx X-Riak-Vclock: a85hYGBgzGDKBVIsbLfe7clgSmTMY2Uw3r3xKF8WAA== Location: /riak/memo/xyz Content-Type: text/plain Link: </riak/memo>; rel="up" Etag: MY6SrlVU7iWVVCndk47NB Last-Modified: Wed, 14 Jul 2010 04:38:11 GMT my reading list: New York Times, Wired --SRzlI2jh68aWdVONf9n1yfDBEVx X-Riak-Vclock: a85hYGBgzGDKBVIsDByHMjOYEhnzWBksd288ypcFAA== Location: /riak/memo/abc Content-Type: text/plain Link: </riak/memo>; rel="up" Etag: 5sTdNwHNK2rykq4kqRSMtW Last-Modified: Wed, 14 Jul 2010 04:38:17 GMT todos: have meeting, make phone call --SRzlI2jh68aWdVONf9n1yfDBEVx-- --W6v94jEJ22hI5cfwbqinnGBmwpV--