# HBase REST

This package provides a RESTful Web service front end for HBase.

## Table Of Contents

1. Deployment

1. Daemon
2. Servlet

2. Representational State Transfer
3. Resource Identifiers
4. Operations

1. Query Software Version
2. Query Storage Cluster Version
3. Query Storage Cluster Status
4. Query Table List
5. Query Table Schema
6. Create Table Or Update Table Schema
7. Query Table Metadata
8. Delete Table
9. Cell Query (Single Value)
10. Cell or Row Query (Multiple Values)
11. Cell Store (Single)
12. Cell Store (Multiple)
13. Row, Column, or Cell Delete
14. Scanner Creation
15. Scanner Get Next
16. Scanner Deletion
17. Stateless scanner

5. XML Schema
6. Protobufs Schema

## Deployment

### Daemon

HBase REST can run as a daemon which starts an embedded Jetty servlet container and deploys the servlet into it.

1. Start the embedded Jetty servlet container:
   - In the foreground:

     > `% ./bin/hbase rest start -p <port>`

     where <port> is optional, and is the port the connector should listen on. (Default is 8080.)

## Representational State Transfer

The terms "representational state transfer" and "REST" were introduced in 2000 in the doctoral dissertation of Roy Fielding, one of the principal authors of the Hypertext Transfer Protocol (HTTP) specification.

A GET to an identifier requests a copy of the information in the supplied content type.

A PUT to an identifier replaces the information. The supplied content type determines how it is to be interpreted.

POST adds information.

DELETE eliminates information.

Database Operations | REST/HTTP Equivalents
CREATE | PUT
READ | GET
UPDATE | POST (update) or PUT (replace)
DELETE | DELETE

## Resource Identifiers

RFC 3968 defines URL syntax:

    scheme://user:pass@example.net:8080/path/to/file;type=foo?name=val#frag
    \_____/  \_______/\___________/\__/\______/\____/\______/\________/\___/
       |         |          |       |     |      |       |       |       |
     scheme   userinfo  hostname  port  path  filename param   query fragment
             \________________________/
                      authority

HBase REST exposes HBase tables, rows, cells, and metadata as URL specified resources.

NOTE: The characters `/`, `:`, and `,` are reserved within row keys, column names, and column qualifiers. Clients must escape them somehow, perhaps by encoding them as hex escapes or by using www-url-encoding. For example, the key:

        http://www.google.com/

should first be encoded as:

        http%3A%2F%2Fwww.google.com%2F

to produce a path like:

        /SomeTable/http%3A%2F%2Fwww.google.com%2F/someColumn:qualifier

### Addressing for cell or row query (GET)

        path := '/' <table>
                '/' <row>
                ( '/' ( <column> ( ':' <qualifier> )?
                        ( ',' <column> ( ':' <qualifier> )? )+ )?
                    ( '/' ( <start-timestamp> ',' )? <end-timestamp> )? )?
        query := ( '?' 'v' '=' <num-versions> )?

### Addressing for single value store (PUT)

Address with table, row, column (and optional qualifier), and optional timestamp.

        path := '/' <table> '/' <row> '/' <column> ( ':' <qualifier> )?
                  ( '/' <timestamp> )?

### Addressing for multiple (batched) value store (PUT)

        path := '/' <table> '/' <false-row-key>

### Addressing for row, column, or cell DELETE

        path := '/' <table>
                '/' <row>
                ( '/' <column> ( ':' <qualifier> )?
                  ( '/' <timestamp> )? )?

### Addressing for table creation or schema update (PUT or POST), schema query (GET), or delete (DELETE)

        path := '/' <table> / 'schema'

### Addressing for scanner creation (POST)

        path := '/' <table> '/' 'scanner'

### Addressing for scanner next item (GET)

        path := '/' <table> '/' 'scanner' '/' <scanner-id>

### Addressing for scanner deletion (DELETE)

        path := '/' <table> '/' '%scanner' '/' <scanner-id>

## Operations

### Query Software Version

    GET /version

Returns the software version. Set Accept header to `text/plain` for plain text output. Set Accept header to `text/xml` for XML reply. Set Accept header to `application/json` for JSON reply. Set Accept header to `application/x-protobuf` for protobufs.

If not successful, returns appropriate HTTP error status code. If successful, returns the software version.

Examples:

> `% curl http://localhost:8000/version
> HTTP/1.1 200 OK
> Content-Length: 149
> Cache-Control: no-cache
> Content-Type: text/plain
> Stargate 0.0.1 [JVM: Sun Microsystems Inc. 1.6.0_13-11.3-b02] [OS: Linux 2.6.
> 18-128.1.6.el5.centos.plusxen amd64] [Jetty: 6.1.14] [Jersey: 1.1.0-ea]
> % curl -H "Accept: text/xml" http://localhost:8000/version
> HTTP/1.1 200 OK
> Cache-Control: no-cache
> Content-Type: text/xml
> Content-Length: 212
> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
> <Version Stargate="0.0.1" OS="Linux 2.6.18-128.1.6.el5.centos.plusxen amd64"
> JVM="Sun Microsystems Inc. 1.6.0_13-11.3-b02" Jetty="6.1.14" Jersey="1.1.0-e
> a"/>
> % curl -H "Accept: application/json" http://localhost:8000/version
> HTTP/1.1 200 OK
> Cache-Control: no-cache
> Content-Type: application/json
> Transfer-Encoding: chunked
> {"@Stargate":"0.0.1","@OS":"Linux 2.6.18-128.1.6.el5.centos.plusxen amd64","@
> JVM":"Sun Microsystems Inc. 1.6.0_13-11.3-b02","@Jetty":"6.1.14","@Jersey":"1
> .1.0-ea"}
> % curl -H "Accept: application/x-protobuf" http://localhost:8000/version
> HTTP/1.1 200 OK
> Content-Length: 113
> Cache-Control: no-cache
> Content-Type: application/x-protobuf
> 000000 0a 05 30 2e 30 2e 31 12 27 53 75 6e 20 4d 69 63
> 000010 72 6f 73 79 73 74 65 6d 73 20 49 6e 63 2e 20 31
> 000020 2e 36 2e 30 5f 31 33 2d 31 31 2e 33 2d 62 30 32
> 000030 1a 2d 4c 69 6e 75 78 20 32 2e 36 2e 31 38 2d 31
> 000040 32 38 2e 31 2e 36 2e 65 6c 35 2e 63 65 6e 74 6f
> 000050 73 2e 70 6c 75 73 78 65 6e 20 61 6d 64 36 34 22
> 000060 06 36 2e 31 2e 31 34 2a 08 31 2e 31 2e 30 2d 65
> 000070 61
> `

### Query Storage Cluster Version

    GET /version/cluster

Returns version information regarding the HBase cluster backing the Stargate instance.

Examples:

> `% curl http://localhost:8000/version/cluster
> HTTP/1.1 200 OK
> Content-Length: 6
> Cache-Control: no-cache
> Content-Type: text/plain
> 0.20.0
> % curl -H "Accept: text/xml" http://localhost:8000/version/cluster
> HTTP/1.1 200 OK
> Cache-Control: no-cache
> Content-Type: text/xml
> Content-Length: 94
> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
> <ClusterVersion>0.20.0</ClusterVersion>
> % curl -H "Accept: application/json" http://localhost:8000/version/cluster
> HTTP/1.1 200 OK
> Cache-Control: no-cache
> Content-Type: application/json
> Transfer-Encoding: chunked
> "0.20.0"
> `

### Query Storage Cluster Status

    GET /status/cluster

Returns detailed status on the HBase cluster backing the Stargate instance.

Examples:

> `% curl http://localhost:8000/status/cluster
> `

>     HTTP/1.1 200 OK
>     Content-Length: 839
>     Cache-Control: no-cache
>     Content-Type: text/plain

>     1 live servers, 0 dead servers, 13.0000 average load

>     1 live servers
>         test:37154 1244960965781
>             requests=1, regions=13

>             urls,http|www.legacy.com|80|site=Legacy|aamsz=300x250||position=1|prod
>               =1,1244851990859
>             urls,http|weather.boston.com|80|LYNX.js,1244851990859
>             hbase:meta,,1
>             content,601292a839b95e50200d8f8767859864,1244869158156
>             content,9d7f3aeb2a5c1e2b45d690a91de3f23c,1244879698031
>             content,7f6d48830ef51d635e9a5b672e79a083,1244879698031
>             content,3ef16d776603bf9b9e775c9ceb64860f,1244869158156
>             urls,,1244851989250
>             urls,http|groups.google.com|80|groups|img|card_left.gif,1244851989250
>             content,deafed2f90f718d72caaf87bd6c27d04,1244870320343
>             content,bcf91ecf78ea72a33faccfb8e6b5d900,1244870320343
>             -ROOT-,,0
>             content,,1244851999187

> `% curl -H "Accept: text/xml" http://localhost:8000/status/cluster
> HTTP/1.1 200 OK
> Cache-Control: no-cache
> Content-Type: text/xml
> Content-Length: 1301
> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
> <ClusterStatus requests="1" regions="13" averageLoad="13.0"><DeadNodes/><LiveN
> odes><Node startCode="1244960965781" requests="1" name="test:37154"><Region na
> me="dXJscyxodHRwfHd3dy5sZWdhY3kuY29tfDgwfHNpdGU9TGVnYWN5fGFhbXN6PTMwMHgyNTB8YX
> JlYT1DSlDQaElDQUdPVFJJQlVORS4yMXx6b25lPUhvbWV8cG9zaXRpb249MXxwcm9kPTEsMTI0NDg1
> MTk5MDg1OQ=="/><Region name="dXJscyxodHRwfHdlYXRoZXIuYm9zdG9uLmNvbXw4MHxMWU5YL
> mpzLDEyNDQ4NTE5OTA4NTk="/><Region name="Lk1FVEEuLCwx"/><Region name="Y29udGVud
> Cw2MDEyOTJhODM5Yjk1ZTUwMjAwZDhmODc2Nzg1OTg2NCwxMjQ0ODY5MTU4MTU2"/><Region name
> ="Y29udGVudCw5ZDdmM2FlYjJhNWMxZTJiNDVkNjkwYTkxZGUzZjIzYywxMjQ0ODc5Njk4MDMx"/><
> Region name="Y29udGVudCw3ZjZkNDg4MzBlZjUxZDYzNWU5YTViNjcyZTc5YTA4MywxMjQ0ODc5N
> jk4MDMx"/><Region name="Y29udGVudCwzZWYxNmQ3NzY2MDNiZjliOWU3NzVjOWNlYjY0ODYwZi
> wxMjQ0ODY5MTU4MTU2"/><Region name="dXJscywsMTI0NDg1MTk4OTI1MA=="/><Region name
> ="dXJscyxodHRwfGdyb3Vwcy5nb29nbGUuY29tfDgwfGdyb3Vwc3xpbWd8Y2FyZF9sZWZ0LmdpZiwx
> MjQ0ODUxOTg5MjUw"/><Region name="Y29udGVudCxkZWFmZWQyZjkwZjcxOGQ3MmNhYWY4N2JkN
> mMyN2QwNCwxMjQ0ODcwMzIwMzQz"/><Region name="Y29udGVudCxiY2Y5MWVjZjc4ZWE3MmEzM2
> ZhY2NmYjhlNmI1ZDkwMCwxMjQ0ODcwMzIwMzQz"/><Region name="LVJPT1QtLCww"/><Region
> name="Y29udGVudCwsMTI0NDg1MTk5OTE4Nw=="/></Node></LiveNodes></ClusterStatus>
> % curl -H "Accept: application/json" http://localhost:8000/status/cluster
> HTTP/1.1 200 OK
> Cache-Control: no-cache
> Content-Type: application/json
> Transfer-Encoding: chunked
> {"@requests":"1","@regions":"13","@averageLoad":"13.0","DeadNodes":[],"LiveNod
> es":{"Node":{"@startCode":"1244960965781","@requests":"1","@name":"test:37154"
> ,"Region":[{"@name":"dXJscyxodHRwfHd3dLmpzy5sZWdhY3kuY29tfDgwfHNpdGU9TGVnYWN5f
> GFhbXN6PTMwMHgyNTB8YXJlYT1DSElDQUdPVFJJQlVORS4yMXx6b25lPUhvbWV8cG9zaXRpb249MXx
> wcm9kPTEsMTI0NDg1MTk5MDg1OQ=="},{"@name":"dXJscyxodHRwfHdlYXRoZXIuYm9zdG9uLmNv
> bXw4MHxMWU5YLmpzLDEyNDQ4NTE5OTA4NTk="},{"@name":"Lk1FVEEuLCwx"},{"@name":"Y29u
> dGVudCw2MDEyOTJhODM5Yjk1ZTUwMjAwZDhmODc2Nzg1OTg2NCwxMjQ0ODY5MTU4MTU2"},{"@name
> ":"Y29udGVudCw5ZDdmM2FlYjJhNWMxZTJiNDVkNjkwYTkxZGUzZjIzYywxMjQ0ODc5Njk4MDMx"},
> {"@name":"Y29udGVudCw3ZjZkNDg4MzBlZjUxZDYzNWU5YTViNjcyZTc5YTA4MywxMjQ0ODc5Njk4
> MDMx"},{"@name":"Y29udGVudCwzZWYxNmQ3NzY2MDNiZjliOWU3NzVjOWNlYjY0ODYwZiwxMjQ0O
> DY5MTU4MTU2"},{"@name":"dXJscywsMTI0NDg1MTk4OTI1MA=="},{"@name":"dXJscyxodHRwf
> Gdyb3Vwcy5nb29nbGUuY29tfDgwfGdyb3Vwc3xpbWd8Y2FyZF9sZWZ0LmdpZiwxMjQ0ODUxOTg5MjU
> w"},{"@name":"Y29udGVudCxkZWFmZWQyZjkwZjcxOGQ3MmNhYWY4N2JkNmMyN2QwNCwxMjQ0ODcw
> MzIwMzQz"},{"@name":"Y29udGVudCxiY2Y5MWVjZjc4ZWE3MmEzM2ZhY2NmYjhlNmI1ZDkwMCwxM
> jQ0ODcwMzIwMzQz"},{"@name":"LVJPT1QtLCww"},{"@name":"Y29udGVudCwsMTI0NDg1MTk5O
> TE4Nw=="}]}}}
> `

### Query Table List

    GET /

Retrieves the list of available tables. Set Accept header to `text/plain` for plain text output. Set Accept header to `text/xml` for XML reply. Set Accept header to `application/json` for JSON reply. Set Accept header to `application/x-protobuf` for protobufs. If not successful, returns appropriate HTTP error status code. If successful, returns the table list in the requested encoding.

Examples:

> `% curl http://localhost:8000/
> HTTP/1.1 200 OK
> Content-Length: 13
> Cache-Control: no-cache
> Content-Type: text/plain
> content
> urls
> % curl -H "Accept: text/xml" http://localhost:8000/
> HTTP/1.1 200 OK
> Cache-Control: no-cache
> Content-Type: text/xml
> Content-Length: 121
> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
> <TableList><table name="content"/><table name="urls"/></TableList>
> % curl -H "Accept: application/json" http://localhost:8000/
> HTTP/1.1 200 OK
> Cache-Control: no-cache
> Content-Type: application/json
> Transfer-Encoding: chunked
> {"table":[{"name":"content"},{"name":"urls"}]}
> % curl -H "Accept: application/x-protobuf" http://localhost:8000/
> HTTP/1.1 200 OK
> Content-Length: 15
> Cache-Control: no-cache
> Content-Type: application/x-protobuf
> 000000 0a 07 63 6f 6e 74 65 6e 74 0a 04 75 72 6c 73
> `

### Query Table Schema

    GET /<table>/schema

Retrieves table schema. Set Accept header to `text/plain` for plain text output. Set Accept header to `text/xml` for XML reply. Set Accept header to `application/json` for JSON reply. Set Accept header to `application/x-protobuf` for protobufs. If not successful, returns appropriate HTTP error status code. If successful, returns the table schema in the requested encoding.

Examples:

> `% curl http://localhost:8000/content/schema
> HTTP/1.1 200 OK
> Content-Length: 639
> Cache-Control: no-cache
> Content-Type: text/plain
> { NAME=> 'content', IS_META => 'false', IS_ROOT => 'false', COLUMNS => [ { NA
> ME => 'content', BLOCKSIZE => '65536', BLOOMFILTER => 'false', BLOCKCACHE =>
> 'false', COMPRESSION => 'GZ', LENGTH => '2147483647', VERSIONS => '1', TTL =>
> '-1', IN_MEMORY => 'false' }, { NAME => 'info', BLOCKSIZE => '65536', BLOOMFI
> LTER => 'false', BLOCKCACHE => 'false', COMPRESSION => 'NONE', LENGTH => '214
> 7483647', VERSIONS => '1', TTL => '-1', IN_MEMORY => 'false' }, { NAME => 'ur
> l', BLOCKSIZE => '65536', BLOOMFILTER => 'false', BLOCKCACHE => 'false', COMP
> RESSION => 'NONE', LENGTH => '2147483647', VERSIONS => '1', TTL => '-1', IN_
> MEMORY => 'false' } ] }
> % curl -H "Accept: text/xml" http://localhost:8000/content/schema
> HTTP/1.1 200 OK
> Cache-Control: no-cache
> Content-Type: text/xml
> Content-Length: 618
> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
> <TableSchema name="content" IS_META="false" IS_ROOT="false"><ColumnSchema nam
> e="content" BLOCKSIZE="65536" BLOOMFILTER="false" BLOCKCACHE="false" COMPRESS
> ION="GZ" LENGTH="2147483647" VERSIONS="1" TTL="-1" IN_MEMORY="false"/><Column
> Schema name="info" BLOCKSIZE="65536" BLOOMFILTER="false" BLOCKCACHE="false" C
> OMPRESSION="NONE" LENGTH="2147483647" VERSIONS="1" TTL="-1" IN_MEMORY="false"
> /><ColumnSchema name="url" BLOCKSIZE="65536" BLOOMFILTER="false"BLOCKCACHE="f
> alse" COMPRESSION="NONE" LENGTH="2147483647" VERSIONS="1" TTL="-1" IN_MEMORY=
> "false"/></TableSchema>
> % curl -H "Accept: application/json" http://localhost:8000/content/schema
> HTTP/1.1 200 OK
> Cache-Control: no-cache
> Content-Type: application/json
> Transfer-Encoding: chunked
> {"@name":"content","@IS_META":"false","@IS_ROOT":"false","ColumnSchema":[{"@n
> ame":"content","@BLOCKSIZE":"65536","@BLOOMFILTER":"false","@BLOCKCACHE":"fal
> se","@COMPRESSION":"GZ","@LENGTH":"2147483647","@VERSIONS":"1","@TTL":"-1","@
> IN_MEMORY":"false"},{"@name":"info","@BLOCKSIZE":"65536","@BLOOMFILTER":"fals
> e","@BLOCKCACHE":"false","@COMPRESSION":"NONE","@LENGTH":"2147483647","@VERSI
> ONS":"1","@TTL":"-1","@IN_MEMORY":"false"},{"@name":"url","@BLOCKSIZE":"65536
> ","@BLOOMFILTER":"false","@BLOCKCACHE":"false","@COMPRESSION":"NONE","@LENGTH
> ":"2147483647","@VERSIONS":"1","@TTL":"-1","@IN_MEMORY":"false"}]}
> % curl -H "Accept: application/x-protobuf" http://localhost:8000/content/schema
> HTTP/1.1 200 OK
> Content-Length: 563
> Cache-Control: no-cache
> Content-Type: application/x-protobuf
> 000000 0a 07 63 6f 6e 74 65 6e 74 12 10 0a 07 49 53 5f
> 000010 4d 45 54 41 12 05 66 61 6c 73 65 12 10 0a 07 49
> 000020 53 5f 52 4f 4f 54 12 05 66 61 6c 73 65 1a a7 01
> 000030 12 12 0a 09 42 4c 4f 43 4b 53 49 5a 45 12 05 36
> [...]
> 000230 4f 4e 45
> `

### Create Table Or Update Table Schema

    PUT /<table>/schema

    POST /<table>/schema

Uploads table schema. PUT or POST creates table as necessary. PUT fully replaces schema. POST modifies schema (add or modify column family). Supply the full table schema for PUT or a well formed schema fragment for POST in the desired encoding. Set Content-Type header to `text/xml` if the desired encoding is XML. Set Content-Type header to `application/json` if the desired encoding is JSON. Set Content-Type header to `application/x-protobuf` if the desired encoding is protobufs. If not successful, returns appropriate HTTP error status code. If successful, returns HTTP 200 status.

### Query Table Metadata

    GET /<table>/regions

Retrieves table region metadata. Set Accept header to `text/plain` for plain text output. Set Accept header to `text/xml` for XML reply. Set Accept header to `application/json` for JSON reply. Set Accept header to `application/x-protobuf` for protobufs. If not successful, returns appropriate HTTP error status code. If successful, returns the table region metadata in the requested encoding.

Examples:

> `% curl -H "Accept: text/xml" http://localhost:8000/content/regions
> HTTP/1.1 200 OK
> Cache-Control: no-cache
> Content-Type: text/xml
> Content-Length: 1555
> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
> <TableInfo name="content"><Region location="test:51025" endKey="M2VmMTZkNzc2Nj
> AzYmY5YjllNzc1YzljZWI2NDg2MGY=" startKey="" id="1244851999187" name="content,,
> 1244851999187"/><Region location="test:51025" endKey="NjAxMjkyYTgzOWI5NWU1MDIw
> MGQ4Zjg3Njc4NTk4NjQ=" startKey="M2VmMTZkNzc2NjAzYmY5YjllNzc1YzljZWI2NDg2MGY="
> id="1244869158156" name="content,3ef16d776603bf9b9e775c9ceb64860f,124486915815
> 6"/><Region location="test:51025" endKey="N2Y2ZDQ4ODMwZWY1MWQ2MzVlOWE1YjY3MmU3
> OWEwODM=" startKey="NjAxMjkyYTgzOWI5NWU1MDIwMGQ4Zjg3Njc4NTk4NjQ=" id="12448691
> 58156" name="content,601292a839b95e50200d8f8767859864,1244869158156"/><Region
> location="test:51025" endKey="OWQ3ZjNhZWIyYTVjMWUyYjQ1ZDY5MGE5MWRlM2YyM2M=" st
> artKey="N2Y2ZDQ4ODMwZWY1MWQ2MzVlOWE1YjY3MmU3OWEwODM=" id="1244879698031" name=
> "content,7f6d48830ef51d635e9a5b672e79a083,1244879698031"/><Region location="te
> st:51025" endKey="YmNmOTFlY2Y3OGVhNzJhMzNmYWNjZmI4ZTZiNWQ5MDA=" startKey="OWQ3
> ZjNhZWIyYTVjMWUyYjQ1ZDY5MGE5MWRlM2YyM2M=" id="1244879698031" name="content,9d7
> f3aeb2a5c1e2b45d690a91de3f23c,1244879698031"/><Region location="test:51025" en
> dKey="ZGVhZmVkMmY5MGY3MThkNzJjYWFmODdiZDZjMjdkMDQ=" startKey="YmNmOTFlY2Y3OGVh
> NzJhMzNmYWNjZmI4ZTZiNWQ5MDA=" id="1244870320343" name="content,bcf91ecf78ea72a
> 33faccfb8e6b5d900,1244870320343"/><Region location="test:51025" endKey="" star
> tKey="ZGVhZmVkMmY5MGY3MThkNzJjYWFmODdiZDZjMjdkMDQ=" id="1244870320343" name="c
> ontent,deafed2f90f718d72caaf87bd6c27d04,1244870320343"/></TableInfo>
> % curl -H "Accept: application/json" http://localhost:8000/content/regions
> HTTP/1.1 200 OK
> Cache-Control: no-cache
> Content-Type: application/json
> Transfer-Encoding: chunked
> {"@name":"content","Region":[{"@location":"test:51025","@endKey":"M2VmMTZkNzc2
> NjAzYmY5YjllNzc1YzljZWI2NDg2MGY=","@startKey":"","@id":"1244851999187","@name"
> :"content,,1244851999187"},{"@location":"test:51025","@endKey":"NjAxMjkyYTgzOW
> I5NWU1MDIwMGQ4Zjg3Njc4NTk4NjQ=","@startKey":"M2VmMTZkNzc2NjAzYmY5YjllNzc1YzljZ
> WI2NDg2MGY=","@id":"1244869158156","@name":"content,3ef16d776603bf9b9e775c9ceb
> 64860f,1244869158156"},{"@location":"test:51025","@endKey":"N2Y2ZDQ4ODMwZWY1MW
> Q2MzVlOWE1YjY3MmU3OWEwODM=","@startKey":"NjAxMjkyYTgzOWI5NWU1MDIwMGQ4Zjg3Njc4N
> Tk4NjQ=","@id":"1244869158156","@name":"content,601292a839b95e50200d8f87678598
> 64,1244869158156"},{"@location":"test:51025","@endKey":"OWQ3ZjNhZWIyYTVjMWUyYj
> Q1ZDY5MGE5MWRlM2YyM2M=","@startKey":"N2Y2ZDQ4ODMwZWY1MWQ2MzVlOWE1YjY3MmU3OWEwO
> DM=","@id":"1244879698031","@name":"content,7f6d48830ef51d635e9a5b672e79a083,1
> 244879698031"},{"@location":"test:51025","@endKey":"YmNmOTFlY2Y3OGVhNzJhMzNmYW
> NjZmI4ZTZiNWQ5MDA=","@startKey":"OWQ3ZjNhZWIyYTVjMWUyYjQ1ZDY5MGE5MWRlM2YyM2M="
> ,"@id":"1244879698031","@name":"content,9d7f3aeb2a5c1e2b45d690a91de3f23c,12448
> 79698031"},{"@location":"test:51025","@endKey":"ZGVhZmVkMmY5MGY3MThkNzJjYWFmOD
> diZDZjMjdkMDQ=","@startKey":"YmNmOTFlY2Y3OGVhNzJhMzNmYWNjZmI4ZTZiNWQ5MDA=","@i
> d":"1244870320343","@name":"content,bcf91ecf78ea72a33faccfb8e6b5d900,124487032
> 0343"},{"@location":"test:51025","@endKey":"","@startKey":"ZGVhZmVkMmY5MGY3MTh
> kNzJjYWFmODdiZDZjMjdkMDQ=","@id":"1244870320343","@name":"content,deafed2f90f7
> 18d72caaf87bd6c27d04,1244870320343"}]}
> % curl -H "Accept: application/x-protobuf" http://localhost:8000/content/regions
> HTTP/1.1 200 OK
> Content-Length: 961
> Cache-Control: no-cache
> Content-Type: application/x-protobuf
> 000000 0a 07 63 6f 6e 74 65 6e 74 12 53 0a 16 63 6f 6e
> 000010 74 65 6e 74 2c 2c 31 32 34 34 38 35 31 39 39 39
> 000020 31 38 37 12 00 1a 20 33 65 66 31 36 64 37 37 36
> 000030 36 30 33 62 66 39 62 39 65 37 37 35 63 39 63 65
> [...]
> 0003c0 35
> `

### Delete Table

    DELETE /<table>/schema

Deletes a table. If not successful, returns appropriate HTTP error status code. If successful, returns HTTP 200 status.

NOTE: `DELETE /<table>` will not work

Examples:

> `% telnet localhost 8000
> DELETE http://localhost:8000/test/schema HTTP/1.0
> HTTP/1.1 200 OK
> Content-Length: 0
> `

### Cell Query (Single Value)

    GET /<table>/<row>/
        <column> ( : <qualifier> )?
      ( / <timestamp> )?

Retrieves one cell, with optional specification of timestamp. Set Accept header to `text/xml` for XML reply. Set Accept header to `application/x-protobuf` for protobufs. Set Accept header to `application/octet-stream` for binary. If not successful, returns appropriate HTTP error status code. If successful, returns HTTP 200 status and cell data in the response body in the requested encoding. If the encoding is binary, returns row, column, and timestamp in X headers: `X-Row`, `X-Column`, and `X-Timestamp`, respectively. Depending on the precision of the resource specification, some of the X-headers may be elided as redundant.

Examples:

> `% curl -H "Accept: text/xml" http://localhost:8000/content/00012614f7d43df6418523445a6787d6/content:raw
> HTTP/1.1 200 OK
> Cache-Control: max-age=14400
> Content-Type: text/xml
> Content-Length: 521
> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
> <CellSet><Row key="MDAwMTI2MTRmN2Q0M2RmNjQxODUyMzQ0NWE2Nzg3ZDY="><Cell timesta
> mp="1244880122250" column="Y29udGVudDpyYXc=">PCFET0NUWVBFIEhUTUwgUFVCTElDICItL
> y9JRVRGLy9EVEQgSFRNTCAyLjAvL0VOIj4KPGh0bWw+PGhlYWQ+Cjx0aXRsZT4zMDEgTW92ZWQgUGV
> ybWFuZW50bHk8L3RpdGxlPgo8L2hlYWQ+PGJvZHk+CjxoMT5Nb3ZlZCBQZXJtYW5lbnRseTwvaDE+C
> jxwPlRoZSBkb2N1bWVudCBoYXMgbW92ZWQgPGEgaHJlZj0iaHR0cDovL3R3aXR0ZXIuY29tL2R1bmN
> hbnJpbGV5Ij5oZXJlPC9hPi48L3A+CjwvYm9keT48L2h0bWw+Cg==</Cell></Row></CellSet>
> % curl -H "Accept: application/json" http://localhost:8000/content/00012614f7d43df6418523445a6787d6/content:raw
> HTTP/1.1 200 OK
> Cache-Control: max-age=14400
> Content-Type: application/json
> Transfer-Encoding: chunked
> {"Row":{"@key":"MDAwMTI2MTRmN2Q0M2RmNjQxODUyMzQ0NWE2Nzg3ZDY=","Cell":{"@timest
> amp":"1244880122250","@column":"Y29udGVudDpyYXc=","$":"PCFET0NUWVBFIEhUTUwgUFV
> CTElDICItLy9JRVRGLy9EVEQgSFRNTCAyLjAvL0VOIj4KPGh0bWw+PGhlYWQ+Cjx0aXRsZT4zMDEgT
> W92ZWQgUGVybWFuZW50bHk8L3RpdGxlPgo8L2hlYWQ+PGJvZHk+CjxoMT5Nb3ZlZCBQZXJtYW5lbnR
> seTwvaDE+CjxwPlRoZSBkb2N1bWVudCBoYXMgbW92ZWQgPGEgaHJlZj0iaHR0cDovL3R3aXR0ZXIuY
> 29tL2R1bmNhbnJpbGV5Ij5oZXJlPC9hPi48L3A+CjwvYm9keT48L2h0bWw+Cg=="}}}
> % curl -H "Accept: application/x-protobuf" http://localhost:8000/content/00012614f7d43df6418523445a6787d6/content:raw
> HTTP/1.1 200 OK
> Content-Length: 301
> Cache-Control: max-age=14400
> Content-Type: application/x-protobuf
> 000000 0a aa 02 0a 20 30 30 30 31 32 36 31 34 66 37 64
> 000010 34 33 64 66 36 34 31 38 35 32 33 34 34 35 61 36
> 000020 37 38 37 64 36 12 85 02 12 0b 63 6f 6e 74 65 6e
> 000030 74 3a 72 61 77 18 8a e3 8c c5 9d 24 22 ee 01 3c
> [...]
> 000120 62 6f 64 79 3e 3c 2f 68 74 6d 6c 3e 0a
> % curl -H "Accept: application/octet-stream" http://localhost:8000/content/00012614f7d43df6418523445a6787d6/content:raw
> HTTP/1.1 200 OK
> Content-Length: 238
> Cache-Control: max-age=14400
> X-Timestamp: 1244880122250
> Content-Type: application/octet-stream
> [...]
> `

### Cell or Row Query (Multiple Values)

    GET /<table>/<row>
      ( / ( <column> ( : <qualifier> )?
          ( , <column> ( : <qualifier> )? )+ )?
        ( / ( <start-timestamp> ',' )? <end-timestamp> )? )?
      ( ?v= <num-versions> )?

Retrieves one or more cells from a full row, or one or more specified columns in the row, with optional filtering via timestamp, and an optional restriction on the maximum number of versions to return. Set Accept header to `text/xml` for XML reply. Set Accept header to `application/json` for JSON reply. Set Accept header to `application/x-protobuf` for protobufs. Set Accept header to `application/octet-stream` for binary. If not successful, returns appropriate HTTP error status code. If successful, returns row results in the requested encoding.

NOTE: If binary encoding is requested, only one cell can be returned, the first to match the resource specification. The row, column, and timestamp associated with the cell will be transmitted in X headers: `X-Row`, `X-Column`, and `X-Timestamp`, respectively. Depending on the precision of the resource specification, some of the X-headers may be elided as redundant.

Suffix Globbing

Multiple value queries of a row can optionally append a suffix glob on the row key. This is a restricted form of scanner which will return all values in all rows that have keys which contain the supplied key on their left hand side, for example:

        org.someorg.*
            -> org.someorg.blog
            -> org.someorg.home
            -> org.someorg.www

Examples:

> `% curl -H "Accept: text/xml" http://localhost:8000/urls/https|ad.doubleclick.net|*
> HTTP/1.1 200 OK
> Cache-Control: max-age=14400
> Content-Type: text/xml
> Transfer-Encoding: chunked
> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
> <CellSet><Row key="aHR0cHx3d3cudGVsZWdyYXBoLmNvLnVrfDgwfG5ld3N8d29ybGRuZXdzfG5
> vcnRoYW1lcmljYXx1c2F8NTQ5MTI4NHxBcm5vbGQtU2Nod2FyemVuZWdnZXItdW52ZWlscy1wYXBlc
> mxlc3MtY2xhc3Nyb29tcy1wbGFuLmh0bWw="><Cell timestamp="1244701257843" column="a
> W5mbzpjcmF3bGVyLTEyNDQ3MDEyNTc4NDM=">eyJpcCI6IjIwOC41MS4xMzcuOSIsIm1pbWV0eXBlI
> joidGV4dC9odG1sO2NoYXJzZXQ9SVNPLT
> [...]
> </Cell><Cell timestamp="1244701513390" column="aW5mbzp1cmw=">aHR0cDovL3d3dy50Z
> WxlZ3JhcGguY28udWs6ODAvdGVsZWdyYXBoL3RlbXBsYXRlL3ZlcjEtMC90ZW1wbGF0ZXMvZnJhZ21
> lbnRzL2NvbW1vbi90bWdsQnJhbmRDU1MuanNw</Cell></Row></CellSet>
> % curl -H "Accept: text/xml" http://localhost:8000/content/00012614f7d43df6418523445a6787d6
> HTTP/1.1 200 OK
> Cache-Control: max-age=14400
> Content-Type: text/xml
> Content-Length: 1177
> <CellSet><Row key="MDAwMTI2MTRmN2Q0M2RmNjQxODUyMzQ0NWE2Nzg3ZDY="><Cell timesta
> mp="1244880122250" column="Y29udGVudDpyYXc=">PCFET0NUWVBFIEhUTUwgUFVCTElDICItL
> y9JRVRGLy9EVEQgSFRNTCAyLjAvL0VOIj4KPGh0bWw+PGhlYWQ+Cjx0aXRsZT4zMDEgTW92ZWQgUGV
> ybWFuZW50bHk8L3RpdGxlPgo8L2hlYWQ+PGJvZHk+CjxoMT5Nb3ZlZCBQZXJtYW5lbnRseTwvaDE+C
> jxwPlRoZSBkb2N1bWVudCBoYXMgbW92ZWQgPGEgaHJlZj0iaHR0cDovL3R3aXR0ZXIuY29tL2R1bmN
> hbnJpbGV5Ij5oZXJlPC9hPi48L3A+CjwvYm9keT48L2h0bWw+Cg==</Cell><Cell timestamp="1
> 244880122250" column="aW5mbzpjcmF3bGVyLWh0dHB8d3d3LnR3aXR0ZXIuY29tfDgwfGR1bmNh
> bnJpbGV5LTEyNDQ4ODAxMjIyNTA=">eyJpcCI6IjE2OC4xNDMuMTYyLjY4IiwibWltZXR5cGUiOiJ0
> ZXh0L2h0bWw7IGNoYXJzZXQ9aXNvLTg4NTktMSIsInZpYSI6Imh0dHA6Ly93d3cuaW5xdWlzaXRyLm
> NvbTo4MC8yNTkyNy90b3NoMC1hbmQtdGhlLWRlbWktbW9vcmUtbnNmdy1waWMvIn0=</Cell><Cell
> timestamp="1244880122250" column="aW5mbzpsZW5ndGg=">MjM4</Cell><Cell timestamp
> ="1244880122250" column="aW5mbzptaW1ldHlwZQ==">dGV4dC9odG1sOyBjaGFyc2V0PWlzby0
> 4ODU5LTE=</Cell><Cell timestamp="1244880122250" column="dXJsOmh0dHB8d3d3LnR3aX
> R0ZXIuY29tfDgwfGR1bmNhbnJpbGV5">aHR0cDovL3d3dy50d2l0dGVyLmNvbTo4MC9kdW5jYW5yaW
> xleQ==</Cell></Row></CellSet>
> % curl -H "Accept: application/json" http://localhost:8000/content/00012614f7d43df6418523445a6787d6
> HTTP/1.1 200 OK
> Cache-Control: max-age=14400
> Content-Type: application/json
> Transfer-Encoding: chunked
> {"Row":{"@key":"MDAwMTI2MTRmN2Q0M2RmNjQxODUyMzQ0NWE2Nzg3ZDY=","Cell":[{"@times
> tamp":"1244880122250","@column":"Y29udGVudDpyYXc=","$":"PCFET0NUWVBFIEhUTUwgUF
> VCTElDICItLy9JRVRGLy9EVEQgSFRNTCAyLjAvL0VOIj4KPGh0bWw+PGhlYWQ+Cjx0aXRsZT4zMDEg
> TW92ZWQgUGVybWFuZW50bHk8L3RpdGxlPgo8L2hlYWQ+PGJvZHk+CjxoMT5Nb3ZlZCBQZXJtYW5lbn
> RseTwvaDE+CjxwPlRoZSBkb2N1bWVudCBoYXMgbW92ZWQgPGEgaHJlZj0iaHR0cDovL3R3aXR0ZXIu
> Y29tL2R1bmNhbnJpbGV5Ij5oZXJlPC9hPi48L3A+CjwvYm9keT48L2h0bWw+Cg=="},{"@timestam
> p":"1244880122250","@column":"aW5mbzpjcmF3bGVyLWh0dHB8d3d3LnR3aXR0ZXIuY29tfDgw
> fGR1bmNhbnJpbGV5LTEyNDQ4ODAxMjIyNTA=","$":"eyJpcCI6IjE2OC4xNDMuMTYyLjY4IiwibWl
> tZXR5cGUiOiJ0ZXh0L2h0bWw7IGNoYXJzZXQ9aXNvLTg4NTktMSIsInZpYSI6Imh0dHA6Ly93d3cua
> W5xdWlzaXRyLmNvbTo4MC8yNTkyNy90b3NoMC1hbmQtdGhlLWRlbWktbW9vcmUtbnNmdy1waWMvIn0
> ="},{"@timestamp":"1244880122250","@column":"aW5mbzpsZW5ndGg=","$":"MjM4"},{"@
> timestamp":"1244880122250","@column":"aW5mbzptaW1ldHlwZQ==","$":"dGV4dC9odG1sO
> yBjaGFyc2V0PWlzby04ODU5LTE="},{"@timestamp":"1244880122250","@column":"dXJsOmh
> 0dHB8d3d3LnR3aXR0ZXIuY29tfDgwfGR1bmNhbnJpbGV5","$":"aHR0cDovL3d3dy50d2l0dGVyLm
> NvbTo4MC9kdW5jYW5yaWxleQ=="}]}}
> `

> NOTE: The cell value is given in JSON encoding as the value associated with the key "$".

> `% curl -H "Accept: application/x-protobuf" http://localhost:8000/content/00012614f7d43df6418523445a6787d6
> HTTP/1.1 200 OK
> Content-Length: 692
> Cache-Control: max-age=14400
> Content-Type: application/x-protobuf
> 000000 0a b1 05 0a 20 30 30 30 31 32 36 31 34 66 37 64
> 000010 34 33 64 66 36 34 31 38 35 32 33 34 34 35 61 36
> 000020 37 38 37 64 36 12 85 02 12 0b 63 6f 6e 74 65 6e
> 000030 74 3a 72 61 77 18 8a e3 8c c5 9d 24 22 ee 01 3c
> [...]
> 0002b0 69 6c 65 79
> `

### Cell Store (Single)

    PUT /<table>/<row>/<column>( : <qualifier> )? ( / <timestamp> )?

    POST /<table>/<row>/<column>( : <qualifier> )? ( / <timestamp> )?

Stores cell data into the specified location. If not successful, returns appropriate HTTP error status code. If successful, returns HTTP 200 status. Set Content-Type header to `text/xml` for XML encoding. Set Content-Type header to `application/x-protobuf` for protobufs encoding. Set Content-Type header to `application/octet-stream` for binary encoding. When using binary encoding, optionally, set X-Timestamp header to the desired timestamp.

PUT and POST operations are equivalent here: Specified addresses without existing data will create new values. Specified addresses with existing data will create new versions, overwriting an existing version if all of { row, column:qualifer, timestamp } match that of the existing value.

See "Cell Query (Single Value)" section for encoding examples.

Examples:

> `% curl -H "Content-Type: text/xml" --data '[...]' http://localhost:8000/test/testrow/test:testcolumn
> HTTP/1.1 200 OK
> Content-Length: 0
> `

### Cell Store (Multiple)

    PUT /<table>/<false-row-key>

    POST /<table>/<false-row-key>

Use a false row key. Row, column, and timestamp values in supplied cells override the specifications of the same on the path, allowing for posting of multiple values to a table in batch. If not successful, returns appropriate HTTP error status code. If successful, returns HTTP 200 status. Set Content-Type to `text/xml` for XML encoding. Set Content-Type header to `application/x-protobuf` for protobufs encoding. Supply commit data in the PUT or POST body.

PUT and POST operations are equivalent here: Specified addresses without existing data will create new values. Specified addresses with existing data will create new versions, overwriting an existing version if all of { row, column:qualifer, timestamp } match that of the existing value.

See "Cell or Row Query (Multiple Values)" for encoding examples.

### Row, Column, or Cell Delete

    DELETE /<table>/<row>
      ( / ( <column> ( : <qualifier> )?
        ( / <timestamp> )? )?

Deletes an entire row, a entire column family, or specific cell(s), depending on how specific the data address. If not successful, returns appropriate HTTP error status code. If successful, returns HTTP 200 status.

NOTE: `DELETE /<table>` will not work. Use `DELETE /<table>/schema` instead.

### Scanner Creation

    PUT /<table>/scanner

    POST /<table>/scanner

Allocates a new table scanner. If not successful, returns appropriate HTTP error status code. If successful, returns HTTP 201 status (created) and the URI which should be used to address the scanner, e.g.

> `/<table>/scanner/112876541342014107c0fa92`

Set Content-Type to `text/xml` if supplying an XML scanner specification. Set Content-Type to `application/protobuf` if supplying a protobufs encoded specification.

Examples:

> `% curl -H "Content-Type: text/xml" -d '<Scanner batch="1"/>' http://localhost:8000/content/scanner
> HTTP/1.1 201 Created
> Location: http://localhost:8000/content/scanner/12447063229213b1937
> Content-Length: 0
> `

### Scanner Get Next

    GET /<table>/scanner/<scanner-id>

Returns the values of the next cells found by the scanner, up to the configured batch amount. Set Accept header to `text/xml` for XML encoding. Set Accept header to `application/x-protobuf` for protobufs encoding. Set Accept header to `application/octet-stream` for binary encoding. If not successful, returns appropriate HTTP error status code. If result is successful but the scanner is exhausted, returns HTTP 204 status (no content). Otherwise, returns HTTP 200 status and row and cell data in the response body. See examples from the "Cell or Row Query (Multiple Values)" section.

NOTE: The binary encoding option returns only one cell regardless of the batching parameter supplied during scanner creation. The row, column, and timestamp associated with the cell are transmitted as X-headers: `X-Row`, `X-Column`, and `X-Timestamp` respectively.

Examples:

> `% curl -H "Content-Type: text/xml" http://localhost:8000/content/scanner/12447063229213b1937
> HTTP/1.1 200 OK
> Cache-Control: no-cache
> Content-Type: text/xml
> Content-Length: 589
> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
> <CellSet><Row key="MDAyMDFjMTAwNjk4ZGNkYjU5MDQxNTVkZGQ3OGRlZTk="><Cell timesta
> mp="1244701281234" column="Y29udGVudDpyYXc=">PCFET0NUWVBFIEhUTUwgUFVCTElDICItL
> y9JRVRGLy9EVEQgSFRNTCAyLjAvL0VOIj4KPGh0bWw+PGhlYWQ+Cjx0aXRsZT40MDQgTm90IEZvdW5
> kPC90aXRsZT4KPC9oZWFkPjxib2R5Pgo8aDE+Tm90IEZvdW5kPC9oMT4KPHA+VGhlIHJlcXVlc3RlZ
> CBVUkwgL3JvYm90cy50eHQgd2FzIG5vdCBmb3VuZCBvbiB0aGlzIHNlcnZlci48L3A+Cjxocj4KPGF
> kZHJlc3M+QXBhY2hlLzIuMi4zIChSZWQgSGF0KSBTZXJ2ZXIgYXQgd3gubWduZXR3b3JrLmNvbSBQb
> 3J0IDgwPC9hZGRyZXNzPgo8L2JvZHk+PC9odG1sPgo=</Cell></Row></CellSet>
> % curl -H "Content-Type: application/json" http://localhost:8000/content/scanner/12447063229213b1937
> HTTP/1.1 200 OK
> Cache-Control: no-cache
> Content-Type: application/json
> Transfer-Encoding: chunked
> {"Row":{"@key":"MDAyMDFjMTAwNjk4ZGNkYjU5MDQxNTVkZGQ3OGRlZTk=","Cell":{"@timest
> amp":"1244701281234","@column":"aW5mbzpjcmF3bGVyLWh0dHB8d3gubWduZXR3b3JrLmNvbX
> w4MHxyb2JvdHMudHh0LTEyNDQ3MDEyODEyMzQ=","$":"eyJpcCI6IjE5OS4xOTMuMTAuMTAxIiwib
> WltZXR5cGUiOiJ0ZXh0L2h0bWw7IGNoYXJzZXQ9aXNvLTg4NTktMSIsInZpYSI6Imh0dHA6Ly93eC5
> tZ25ldHdvcmsuY29tOjgwL2pzL2N1cnJlbnRzaGFuZGxlci5qcyJ9"}}}
> % curl -H "Content-Type: application/x-protobuf" http://localhost:8000/content/scanner/12447063229213b1937
> HTTP/1.1 200 OK
> Content-Length: 63
> Cache-Control: no-cache
> Content-Type: application/x-protobuf
> 000000 0a 3d 0a 20 30 30 32 30 31 63 31 30 30 36 39 38
> 000010 64 63 64 62 35 39 30 34 31 35 35 64 64 64 37 38
> 000020 64 65 65 39 12 19 12 0b 69 6e 66 6f 3a 6c 65 6e
> 000030 67 74 68 18 d2 97 e9 ef 9c 24 22 03 32 39 30
> % curl -H "Content-Type: application/octet-stream" http://localhost:8000/content/scanner/12447063229213b1937
> HTTP/1.1 200 OK
> Content-Length: 37
> Cache-Control: no-cache
> X-Column: dXJsOmh0dHB8d3gubWduZXR3b3JrLmNvbXw4MHxyb2JvdHMudHh0
> X-Row: MDAyMDFjMTAwNjk4ZGNkYjU5MDQxNTVkZGQ3OGRlZTk=
> X-Timestamp: 1244701281234
> Content-Type: application/octet-stream
> 000000 68 74 74 70 3a 2f 2f 77 78 2e 6d 67 6e 65 74 77
> 000010 6f 72 6b 2e 63 6f 6d 3a 38 30 2f 72 6f 62 6f 74
> 000020 73 2e 74 78 74
> `

### Scanner Deletion

    DELETE /<table>/scanner/<scanner-id>

Deletes resources associated with the scanner. This is an optional action. Scanners will expire after some globally configurable interval has elapsed with no activity on the scanner. If not successful, returns appropriate HTTP error status code. If successful, returns HTTP status 200.

Examples:

> `% telnet localhost 8000
> DELETE http://localhost:8000/content/scanner/12447063229213b1937 HTTP/1.0
> HTTP/1.1 200 OK
> Content-Length: 0
> `

### Stateless Scanner

        GET /<table>/<optional_row_prefix>*?<scan_parameters>

The current scanner API expects clients to restart scans if there is a REST server failure in the midst. The stateless does not store any state related to scan operation and all the parameters are specified as query parameters.

The following are the scan parameters

1. startrow - The start row for the scan.
2. endrow - The end row for the scan.
3. columns - The columns to scan.
4. starttime, endtime - To only retrieve columns within a specific range of version timestamps, both start and end time must be specified.
5. maxversions - To limit the number of versions of each column to be returned.
6. batchsize - To limit the maximum number of values returned for each call to next().
7. limit - The number of rows to return in the scan operation.

More on start row, end row and limit parameters.

1. If start row, end row and limit not specified, then the whole table will be scanned.
2. If start row and limit (say N) is specified, then the scan operation will return N rows from the start row specified.
3. If only limit parameter is specified, then the scan operation will return N rows from the start of the table.
4. If limit and end row are specified, then the scan operation will return N rows from start of table till the end row. If the end row is reached before N rows ( say M and M < N ), then M rows will be returned to the user.
5. If start row, end row and limit (say N ) are specified and N < number of rows between start row and end row, then N rows from start row will be returned to the user. If N > (number of rows between start row and end row (say M), then M number of rows will be returned to the user.

Examples

>     Lets say we have a table with name "ExampleScanner". On Hbase shell,
>     >> scan 'ExampleScanner'

>     ROW COLUMN+CELL
>     testrow1 column=a:1, timestamp=1389900769772, value=testvalue-a1
>     testrow1 column=b:1, timestamp=1389900780536, value=testvalue-b1
>     testrow2 column=a:1, timestamp=1389900823877, value=testvalue-a2
>     testrow2 column=b:1, timestamp=1389900818233, value=testvalue-b2
>     testrow3 column=a:1, timestamp=1389900847336, value=testvalue-a3
>     testrow3 column=b:1, timestamp=1389900856845, value=testvalue-b3

> -     Scanning the entire table in json

>       curl -H "Accept: application/json" https://localhost:8080/ExampleScanner/*

>   `{"Row":[{"key":"dGVzdHJvdzE=","Cell":[{"column":"YTox","timestamp":1389900769772,
>   "$":"dGVzdHZhbHVlLWEx"},{"column":"Yjox","timestamp":1389900780536,"$":"dGVzdHZhbHVlLWIx"}]},
>   {"key":"dGVzdHJvdzI=","Cell":[{"column":"YTox","timestamp":1389900823877,"$":"dGVzdHZhbHVlLWEy"}
>   {"column":"Yjox","timestamp":1389900818233,"$":"dGVzdHZhbHVlLWIy"}]},{"key":"dGVzdHJvdzM=",
>   "Cell":[{"column":"YTox","timestamp":1389900847336,"$":"dGVzdHZhbHVlLWEz"},{"column":"Yjox",
>   "timestamp":1389900856845,"$":"dGVzdHZhbHVlLWIz"}]}]}
>   `

> -     Scanning the entire table in XML

>       curl -H "Content-Type: text/xml" https://localhost:8080/ExampleScanner/*

>   `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CellSet><
>   Row key="dGVzdHJvdzE="><Cell column="YTox" timestamp="1389900769772">dGVzdHZhbHVlLWEx<
>   /Cell><Cell column="Yjox"timestamp="1389900780536">dGVzdHZhbHVlLWIx</Cell><
>   /Row><Row key="dGVzdHJvdzI="><Cell column="YTox" timestamp="1389900823877">
>   dGVzdHZhbHVlLWEy</Cell><Cell column="Yjox"timestamp="1389900818233">dGVzdHZhbHVlLWIy<
>   /Cell></Row><Row key="dGVzdHJvdzM="><Cell column="YTox" timestamp="1389900847336
>   ">dGVzdHZhbHVlLWEz</Cell><Cell column="Yjox"timestamp="1389900856845">
>   dGVzdHZhbHVlLWIz</Cell></Row></CellSet>
>   `

> -     Scanning the entire table in binary

>       curl -H "Accept: application/protobuf" https://localhost:8080/ExampleScanner/*

>       ^@Ì
>       B
>       ^Htestrow1^R^Z^R^Ca:1^XìÓªä¹("^Ltestvalue-a1^R^Z^R^Cb:1^Xø§«ä¹("^Ltestvalue-b1
>       B
>       ^Htestrow2^R^Z^R^Ca:1^XÅúä¹("^Ltestvalue-a2^R^Z^R^Cb:1^X¹Îä¹("^Ltestvalue-b2
>       B
>       ^Htestrow3^R^Z^R^Ca:1^Xè±¯ä¹("^Ltestvalue-a3^R^Z^R^Cb:1^X<8d>ü¯ä¹("^Ltestvalue-b3

> -     Scanning the first row of table

>       curl -H "Content-Type: text/xml" https://localhost:8080/ExampleScanner/*?limit=1

>   `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CellSet><
>   Row key="dGVzdHJvdzE="><Cell column="YTox" timestamp="1389900769772">
>   dGVzdHZhbHVlLWEx</Cell><Cell column="Yjox"timestamp="1389900780536">
>   dGVzdHZhbHVlLWIx</Cell></Row></CellSet>
>   `

> -     Scanning a given column of table

>       curl -H "Content-Type: text/xml" https://localhost:8080/ExampleScanner/*?columns=a:1

>   `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CellSet><
>   Row key="dGVzdHJvdzE="><Cell column="YTox" timestamp="1389900769772">dGVzdHZhbHVlLWEx<
>   /Cell></Row><Row key="dGVzdHJvdzI="><Cell column="YTox" timestamp=
>   "1389900823877">dGVzdHZhbHVlLWEy</Cell></Row><Row key="dGVzdHJvdzM="><
>   Cell column="YTox" timestamp="1389900847336">dGVzdHZhbHVlLWEz</Cell><
>   /Row></CellSet>
>   `

> -     Scanning more than one column of table

>       curl -H "Content-Type: text/xml" https://localhost:8080/ExampleScanner/*?columns=a:1,b:1

>   `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CellSet><
>   Row key="dGVzdHJvdzE="><Cell column="YTox" timestamp="1389900769772">
>   dGVzdHZhbHVlLWEx</Cell><Cell column="Yjox"timestamp="1389900780536">
>   dGVzdHZhbHVlLWIx</Cell></Row><Row key="dGVzdHJvdzI="><
>   Cell column="YTox" timestamp="1389900823877">dGVzdHZhbHVlLWEy</Cell><
>   Cell column="Yjox"timestamp="1389900818233">dGVzdHZhbHVlLWIy</Cell><
>   /Row><Row key="dGVzdHJvdzM="><Cell column="YTox" timestamp="1389900847336">
>   dGVzdHZhbHVlLWEz</Cell><Cell column="Yjox"timestamp="1389900856845">
>   dGVzdHZhbHVlLWIz</Cell></Row></CellSet>
>   `

> -     Scanning table with start row and limit

>       curl -H "Content-Type: text/xml" https://localhost:8080/ExampleScanner/*?startrow=testrow1&limit=2

>   `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CellSet><
>   Row key="dGVzdHJvdzE="><Cell column="YTox" timestamp="1389900769772">dGVzdHZhbHVlLWEx<
>   /Cell><Cell column="Yjox"timestamp="1389900780536">dGVzdHZhbHVlLWIx</Cell><
>   /Row><Row key="dGVzdHJvdzI="><Cell column="YTox" timestamp="1389900823877">
>   dGVzdHZhbHVlLWEy</Cell><Cell column="Yjox"
>   timestamp="1389900818233">dGVzdHZhbHVlLWIy</Cell></Row></CellSet>
>   `

> -     Scanning with start and end time

>       curl -H "Content-Type: text/xml" https://localhost:8080/ExampleScanner/*?starttime=1389900769772&endtime=1389900800000

>   `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CellSet><
>   Row key="dGVzdHJvdzE="><Cell column="YTox" timestamp="1389900769772">dGVzdHZhbHVlLWEx<
>   /Cell><Cell column="Yjox"timestamp="1389900780536">dGVzdHZhbHVlLWIx</Cell><
>   /Row></CellSet>
>   `

> -     Scanning with row prefix

>       curl -H "Content-Type: text/xml" https://localhost:8080/ExampleScanner/test*

>   `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CellSet><
>   Row key="dGVzdHJvdzE="><Cell column="YTox" timestamp="1389900769772">dGVzdHZhbHVlLWEx<
>   /Cell><Cell column="Yjox"timestamp="1389900780536">dGVzdHZhbHVlLWIx</Cell><
>   /Row><Row key="dGVzdHJvdzI="><Cell column="YTox" timestamp="1389900823877">
>   dGVzdHZhbHVlLWEy</Cell><Cell column="Yjox"timestamp="1389900818233">
>   dGVzdHZhbHVlLWIy</Cell></Row><Row key="dGVzdHJvdzM="><
>   Cell column="YTox" timestamp="1389900847336">dGVzdHZhbHVlLWEz</Cell><
>   Cell column="Yjox"timestamp="1389900856845">dGVzdHZhbHVlLWIz</Cell><
>   /Row></CellSet>
>   `

## XML Schema

    <schema targetNamespace="StargateSchema" elementFormDefault="qualified"
    xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="StargateSchema">

        <element name="CellSet" type="tns:CellSet"></element>

        <complexType name="CellSet">
          <sequence>
            <element name="row" type="tns:Row" maxOccurs="unbounded" minOccurs="1"></element>
          </sequence>
        </complexType>

        <complexType name="Row">
          <sequence>
            <element name="key" type="base64Binary"></element>
            <element name="cell" type="tns:Cell" maxOccurs="unbounded" minOccurs="1"></element>
          </sequence>
        </complexType>

        <complexType name="Cell">
          <sequence>
            <element name="value" maxOccurs="1" minOccurs="1"><simpleType><restriction base="base64Binary"></restriction></simpleType></element>
          </sequence>
          <attribute name="column" type="base64Binary" />
          <attribute name="timestamp" type="int" />
        </complexType>

        <element name="Version" type="tns:Version"></element>

        <complexType name="Version">
          <attribute name="Stargate" type="string"></attribute>
          <attribute name="JVM" type="string"></attribute>
          <attribute name="OS" type="string"></attribute>
          <attribute name="Server" type="string"></attribute>
          <attribute name="Jersey" type="string"></attribute>
        </complexType>

        <element name="TableList" type="tns:TableList"></element>

        <complexType name="TableList">
          <sequence>
            <element name="table" type="tns:Table" maxOccurs="unbounded" minOccurs="1"></element>
          </sequence>
        </complexType>

        <complexType name="Table">
          <sequence>
            <element name="name" type="string"></element>
          </sequence>
        </complexType>

        <element name="TableInfo" type="tns:TableInfo"></element>

        <complexType name="TableInfo">
          <sequence>
            <element name="region" type="tns:TableRegion" maxOccurs="unbounded" minOccurs="1"></element>
          </sequence>
          <attribute name="name" type="string"></attribute>
        </complexType>

        <complexType name="TableRegion">
          <attribute name="name" type="string"></attribute>
          <attribute name="id" type="int"></attribute>
          <attribute name="startKey" type="base64Binary"></attribute>
          <attribute name="endKey" type="base64Binary"></attribute>
          <attribute name="location" type="string"></attribute>
        </complexType>

        <element name="TableSchema" type="tns:TableSchema"></element>

        <complexType name="TableSchema">
          <sequence>
            <element name="column" type="tns:ColumnSchema" maxOccurs="unbounded" minOccurs="1"></element>
          </sequence>
          <attribute name="name" type="string"></attribute>
          <anyAttribute></anyAttribute>
        </complexType>

        <complexType name="ColumnSchema">
          <attribute name="name" type="string"></attribute>
          <anyAttribute></anyAttribute>
        </complexType>

        <element name="Scanner" type="tns:Scanner"></element>

        <complexType name="Scanner">
          <attribute name="startRow" type="base64Binary"></attribute>
          <attribute name="endRow" type="base64Binary"></attribute>
          <attribute name="columns" type="base64Binary"></attribute>
          <attribute name="batch" type="int"></attribute>
          <attribute name="startTime" type="int"></attribute>
          <attribute name="endTime" type="int"></attribute>
        </complexType>

        <element name="StorageClusterVersion"
          type="tns:StorageClusterVersion">
        </element>

        <complexType name="StorageClusterVersion">
          <attribute name="version" type="string"></attribute>
        </complexType>

        <element name="StorageClusterStatus"
          type="tns:StorageClusterStatus">
        </element>

        <complexType name="StorageClusterStatus">
          <sequence>
            <element name="liveNode" type="tns:Node"
              maxOccurs="unbounded" minOccurs="0">
            </element>
            <element name="deadNode" type="string" maxOccurs="unbounded"
              minOccurs="0">
            </element>
          </sequence>
          <attribute name="regions" type="int"></attribute>
          <attribute name="requests" type="int"></attribute>
          <attribute name="averageLoad" type="float"></attribute>
        </complexType>

        <complexType name="Node">
          <sequence>
            <element name="region" type="tns:Region" maxOccurs="unbounded" minOccurs="0"></element>
          </sequence>
          <attribute name="name" type="string"></attribute>
          <attribute name="startCode" type="int"></attribute>
          <attribute name="requests" type="int"></attribute>
          <attribute name="heapSizeMB" type="int"></attribute>
          <attribute name="maxHeapSizeMB" type="int"></attribute>
        </complexType>

        <complexType name="Region">
          <attribute name="name" type="base64Binary"></attribute>
          <attribute name="stores" type="int"></attribute>
          <attribute name="storefiles" type="int"></attribute>
          <attribute name="storefileSizeMB" type="int"></attribute>
          <attribute name="memstoreSizeMB" type="int"></attribute>
          <attribute name="storefileIndexSizeMB" type="int"></attribute>
        </complexType>
    </schema>

## Protobufs Schema

    message Version {
      optional string stargateVersion = 1;
      optional string jvmVersion = 2;
      optional string osVersion = 3;
      optional string serverVersion = 4;
      optional string jerseyVersion = 5;
    }

    message StorageClusterStatus {
      message Region {
        required bytes name = 1;
        optional int32 stores = 2;
        optional int32 storefiles = 3;
        optional int32 storefileSizeMB = 4;
        optional int32 memstoreSizeMB = 5;
        optional int32 storefileIndexSizeMB = 6;
      }
      message Node {
        required string name = 1;    // name:port
        optional int64 startCode = 2;
        optional int32 requests = 3;
        optional int32 heapSizeMB = 4;
        optional int32 maxHeapSizeMB = 5;
        repeated Region regions = 6;
      }
      // node status
      repeated Node liveNodes = 1;
      repeated string deadNodes = 2;
      // summary statistics
      optional int32 regions = 3;
      optional int32 requests = 4;
      optional double averageLoad = 5;
    }

    message TableList {
      repeated string name = 1;
    }

    message TableInfo {
      required string name = 1;
      message Region {
        required string name = 1;
        optional bytes startKey = 2;
        optional bytes endKey = 3;
        optional int64 id = 4;
        optional string location = 5;
      }
      repeated Region regions = 2;
    }

    message TableSchema {
      optional string name = 1;
      message Attribute {
        required string name = 1;
        required string value = 2;
      }
      repeated Attribute attrs = 2;
      repeated ColumnSchema columns = 3;
      // optional helpful encodings of commonly used attributes
      optional bool inMemory = 4;
      optional bool readOnly = 5;
    }

    message ColumnSchema {
      optional string name = 1;
      message Attribute {
        required string name = 1;
        required string value = 2;
      }
      repeated Attribute attrs = 2;
      // optional helpful encodings of commonly used attributes
      optional int32 ttl = 3;
      optional int32 maxVersions = 4;
      optional string compression = 5;
    }

    message Cell {
      optional bytes row = 1;       // unused if Cell is in a CellSet
      optional bytes column = 2;
      optional int64 timestamp = 3;
      optional bytes data = 4;
    }

    message CellSet {
      message Row {
        required bytes key = 1;
        repeated Cell values = 2;
      }
      repeated Row rows = 1;
    }

    message Scanner {
      optional bytes startRow = 1;
      optional bytes endRow = 2;
      repeated bytes columns = 3;
      optional int32 batch = 4;
      optional int64 startTime = 5;
      optional int64 endTime = 6;
    }