Source

riak / doc / raw-http-howto.txt

How to Use the "Raw" HTTP Interface

If the documents you want to store in Riak are JSON shaped, you'll
probably find Jiak, the JSON-HTTP interface more appropriate for your
needs.  But, if your data is in some other format, you'll find
raw_http_resource far more useful.

Step 1 in using the raw HTTP interface is to enable the Riak web
interface.  Add these two lines to your riak config:

   {riak_web_ip, "127.0.0.1"}.
   {riak_web_port, 8098}.

Now start Riak with your config file, and you'll find the raw HTTP
interface at http://127.0.0.1:8098/raw/...  If you'd rather have some
prefix other than "raw", add another line to your config:

   {raw_name, "myrawprefix"}.

If you plan on only or mostly using the raw HTTP interface, you'll
also find it convenient to set the default linkfun for your buckets.
One more line for your config file:

   {default_bucket_props, [{linkfun, {modfun, raw_link_walker_resource, mapreduce_linkfun}}]}.

You'll find that all buckets exist, and are ready to give you details
about themselves at /raw/BucketName:

   $ curl -i http://127.0.0.1:8098/raw/example
   HTTP/1.1 200 OK
   Vary: Accept-Encoding
   Server: MochiWeb/1.1 WebMachine/1.4 (our dis is finally out)
   Date: Fri, 30 Oct 2009 02:36:46 GMT
   Content-Type: application/json
   Content-Length: 272

   {"props":{"name":"example","allow_mult":false,"big_vclock":50,"chash_keyfun":{"mod":"riak_util","fun":"chash_std_keyfun"},"linkfun":{"mod":"raw_link_walker_resource","fun":"mapreduce_linkfun"},"n_val":3,"old_vclock":86400,"small_vclock":10,"young_vclock":21600},"keys":[]}

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/raw/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/raw/example/foo --data "I have a document."

The raw 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/raw/example/foo
   HTTP/1.1 200 OK
   X-Riak-Vclock: a85hYGBgzGDKBVIsbIt4J2UwJTLmsTIEn4s7wpcFAA==
   Vary: Accept-Encoding
   Server: MochiWeb/1.1 WebMachine/1.4 (our dis is finally out)
   Link: </raw/example>; rel="up"
   Last-Modified: Fri, 30 Oct 2009 02:41:23 GMT
   ETag: 3ntEVjk1ubJ8fVWZRsuuij
   Date: Fri, 30 Oct 2009 02:43:44 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: a85hYGBgzGDKBVIsbIt4J2UwJTLmsTIEn4s7wpcFAA==" \
     http://127.0.0.1:8098/raw/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/raw/example/foo
   HTTP/1.1 200 OK
   X-Riak-Vclock: a85hYGBgymDKBVIsbJZ3MjOYEhnzWBl8zscd4YMJL+KdBBUOPgcUzgIA
   Vary: Accept-Encoding
   Server: MochiWeb/1.1 WebMachine/1.4 (our dis is finally out)
   Link: </raw/example>; rel="up"
   Last-Modified: Fri, 30 Oct 2009 02:45:32 GMT
   ETag: ZzCoM94wkIPIs9j1ygTu
   Date: Fri, 30 Oct 2009 02:45:38 GMT
   Content-Type: text/plain
   Content-Length: 27

   I have a modified document.

At this point, with your document in Riak, if you were to issue that
bucket-GET again, you'd find that the "keys" field now includes the
"foo" key under which your document is stored:

   $ curl http://127.0.0.1:8098/raw/example
   {"props":{"n_val":4,"name":"example","allow_mult":false,"big_vclock":50,"chash_keyfun":{"mod":"riak_util","fun":"chash_std_keyfun"},"linkfun":{"mod":"raw_link_walker_resource","fun":"mapreduce_linkfun"},"old_vclock":86400,"small_vclock":10,"young_vclock":21600},"keys":["foo"]}

To delete a document, simply issue a DELETE request:

   $ curl -X DELETE http://127.0.0.1:8098/raw/example/foo

You'll find that further GETs of that URL return status code 404, and
a bucket-GET will no longer list the "foo" key.

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/raw/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/raw/example \
     --data "{\"props\":{\"allow_mult\":true}}
   $ curl -X PUT -H "content-type: text/plain" \
     http://127.0.0.1:8098/raw/example/sib --data "one thing"
   $ curl -X PUT -H "content-type: text/plain" \
     http://127.0.0.1:8098/raw/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/raw/example/sib
   HTTP/1.1 300 Multiple Choices
   X-Riak-Vclock: a85hYGBgzmDKBVJszUnMSekGGUyJjHmsDE6X4o7wQSRYWLQeTYYK2yAJszX7RCCrzgIA
   Vary: Accept-Encoding
   Server: MochiWeb/1.1 WebMachine/1.4 (our dis is finally out)
   Date: Fri, 30 Oct 2009 03:03:47 GMT
   Content-Type: text/plain
   Content-Length: 56
   
   Siblings:
   5y8TG9rlUoQwT3WZQan7KI
   5huW49JytEFZIJG9ryTU8U

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/raw/example/sib?vtag=5huW49JytEFZIJG9ryTU8U
   one thing
   $ curl http://127.0.0.1:8098/raw/example/sib?vtag=5y8TG9rlUoQwT3WZQan7KI
   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/raw/sib/one
   HTTP/1.1 300 Multiple Choices
   X-Riak-Vclock: a85hYGBgz2DKBVJszUlMCj+kMpgSGfNYGVy/xR/hg0iwMPg9FYMK2yELvzwvhEU1yyfGjVDh4hUIYXbJhmaocB5CGGgps/qNZEz1QAm2fc6lyNZmAQA=
   Vary: Accept, Accept-Encoding
   Server: MochiWeb/1.1 WebMachine/1.4 (our dis is finally out)
   Date: Fri, 30 Oct 2009 23:44:52 GMT
   Content-Type: multipart/mixed; boundary=IASZJsIrb8ykNEc1fuue9LitToc
   Content-Length: 361
   
   --IASZJsIrb8ykNEc1fuue9LitToc
   Content-Type: text/plain
   Link: </raw/sib>; rel="up"
   Etag: 6YUKo8vXvtBAXD0Hjy8crv
   Last-Modified: Fri, 30 Oct 2009 18:12:03 GMT
   
   goodbye
   --IASZJsIrb8ykNEc1fuue9LitToc
   Content-Type: text/plain
   Link: </raw/sib>; rel="up"
   Etag: 4XcBgFOm0Ab517wWjNXeWc
   Last-Modified: Fri, 30 Oct 2009 18:11:58 GMT
   
   hello
   --IASZJsIrb8ykNEc1fuue9LitToc--

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: a85hYGBgzmDKBVJszUnMSekGGUyJjHmsDE6X4o7wQSRYWLQeTYYK2yAJszX7RCCrzgIA" \
     http://127.0.0.1:8098/raw/example/sib --data "resolved"

And you'll see that things are back to normal:

   $ curl http://127.0.0.1:8098/raw/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 raw
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
/raw/person/jane:

   Link: </raw/memo/xyz>; riaktag="author"

Multiple links should be separated by commas:

   Link: </raw/memo/xyz>; riaktag="author", </raw/memo/abc>; riaktag="reader"

Performening 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/raw/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/raw/person/jane/memo,author,_

More details about link-walking URL syntax can be found in the Jiak
documentation.

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/raw/memo/xyz \
     --data "my reading list: New York Times, Wired"
   $ curl -X PUT -H "content-type: text/plain" \
     http://127.0.0.1:8098/raw/memo/abc \
     --data "todos: have meeting, make phone call"
   $ curl -X PUT -H "content-type: text/plain" \
     -H "link: </raw/memo/xyz>; riaktag=\"author\", </raw/memo/abc>; riaktag=\"reader\"" \
     http://127.0.0.1:8098/raw/person/jane --data "Name: Jane Doe"

   $ curl -i http://127.0.0.1:8098/raw/person/jane/memo,_,_
   HTTP/1.1 200 OK
   Server: MochiWeb/1.1 WebMachine/1.4 (our dis is finally out)
   Expires: Fri, 30 Oct 2009 16:55:30 GMT
   Date: Fri, 30 Oct 2009 16:45:30 GMT
   Content-Type: multipart/mixed; boundary=DVmSIvK8K2UFitAvniDJt35ZLeX
   Content-Length: 725
   
   
   --DVmSIvK8K2UFitAvniDJt35ZLeX
   Content-Type: multipart/mixed; boundary=V6AxdhwiGzh4MLwdiee2cBWtGug
   
   --V6AxdhwiGzh4MLwdiee2cBWtGug
   Location: /raw/memo/abc
   Content-Type: text/plain
   X-Riak-Vclock: a85hYGBgzGDKBVIsDOf5gjOYEhnzWBlmTow/wpcFAA==
   Link: </raw/memo>; rel="up"
   Etag: 7j63akQj4WqR28GoYjW4hm
   Last-Modified: Fri, 30 Oct 2009 16:34:33 GMT
   
   todos: have meeting, make phone call
   --V6AxdhwiGzh4MLwdiee2cBWtGug
   Location: /raw/memo/xyz
   Content-Type: text/plain
   X-Riak-Vclock: a85hYGBgzGDKBVIsLJWfpTKYEhnzWBlKJ8Yf4csCAA==
   Link: </raw/memo>; rel="up"
   Etag: 5kW1gxTizjTALthrHPjQJ3
   Last-Modified: Fri, 30 Oct 2009 16:33:57 GMT
   
   my reading list: New York Times, Wired
   --V6AxdhwiGzh4MLwdiee2cBWtGug--
   
   --DVmSIvK8K2UFitAvniDJt35ZLeX--
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.