11.1. API Basics

The CouchDB API is the primary method of interfacing to a CouchDB instance.Requests are made using HTTP and requests are used to request information fromthe database, store new data, and perform views and formatting of theinformation stored within the documents.

Requests to the API can be categorised by the different areas of the CouchDBsystem that you are accessing, and the HTTP method used to send the request.Different methods imply different operations, for example retrieval ofinformation from the database is typically handled by the GET operation,while updates are handled by either a POST or PUT request. There aresome differences between the information that must be supplied for thedifferent methods. For a guide to the basic HTTP methods and request structure,see Request Format and Responses.

For nearly all operations, the submitted data, and the returned data structure,is defined within a JavaScript Object Notation (JSON) object. Basic informationon the content and data types for JSON are provided in JSON Basics.

Errors when accessing the CouchDB API are reported using standard HTTP StatusCodes. A guide to the generic codes returned by CouchDB are provided inHTTP Status Codes.

When accessing specific areas of the CouchDB API, specific information andexamples on the HTTP methods and request, JSON structures, and error codes areprovided.

11.1.1. Request Format and Responses

CouchDB supports the following HTTP request methods:

  • GET

Request the specified item. As with normal HTTP requests, the format of theURL defines what is returned. With CouchDB this can include static items,database documents, and configuration and statistical information. In mostcases the information is returned in the form of a JSON document.

  • HEAD

The HEAD method is used to get the HTTP header of a GET requestwithout the body of the response.

  • POST

Upload data. Within CouchDB POST is used to set values, includinguploading documents, setting document values, and starting certainadministration commands.

  • PUT

Used to put a specified resource. In CouchDB PUT is used to create newobjects, including databases, documents, views and design documents.

  • DELETE

Deletes the specified resource, including documents, views, and designdocuments.

  • COPY

A special method that can be used to copy documents and objects.

If you use an unsupported HTTP request type with an URL that does not supportthe specified type then a 405 - Method Not Allowed will be returned,listing the supported HTTP methods. For example:

  1. {
  2. "error":"method_not_allowed",
  3. "reason":"Only GET,HEAD allowed"
  4. }

The CouchDB design document API and the functions when returning HTML (forexample as part of a show or list) enables you to include custom HTTP headersthrough the headers block of the return object.

11.1.2. HTTP Headers

Because CouchDB uses HTTP for all communication, you need to ensure that thecorrect HTTP headers are supplied (and processed on retrieval) so that you getthe right format and encoding. Different environments and clients will be moreor less strict on the effect of these HTTP headers (especially when notpresent). Where possible you should be as specific as possible.

11.1.2.1. Request Headers

  • Accept

Specifies the list of accepted data types to be returned by the server (i.e.that are accepted/understandable by the client). The format should be a listof one or more MIME types, separated by colons.

For the majority of requests the definition should be for JSON data(application/json). For attachments you can either specify the MIME typeexplicitly, or use / to specify that all file types are supported. Ifthe Accept header is not supplied, then the / MIME type is assumed(i.e. client accepts all formats).

The use of Accept in queries for CouchDB is not required, but is highlyrecommended as it helps to ensure that the data returned can be processed bythe client.

If you specify a data type using the Accept header, CouchDB will honorthe specified type in the Content-type header field returned. Forexample, if you explicitly request application/json in the Accept ofa request, the returned HTTP headers will use the value in the returnedContent-type field.

For example, when sending a request without an explicit Accept header, orwhen specifying /:

  1. GET /recipes HTTP/1.1
  2. Host: couchdb:5984
  3. Accept: */*

The returned headers are:

  1. HTTP/1.1 200 OK
  2. Server: CouchDB (Erlang/OTP)
  3. Date: Thu, 13 Jan 2011 13:39:34 GMT
  4. Content-Type: text/plain;charset=utf-8
  5. Content-Length: 227
  6. Cache-Control: must-revalidate

Note

The returned content type is text/plain even though the informationreturned by the request is in JSON format.

Explicitly specifying the Accept header:

  1. GET /recipes HTTP/1.1
  2. Host: couchdb:5984
  3. Accept: application/json

The headers returned include the application/json content type:

  1. HTTP/1.1 200 OK
  2. Server: CouchDB (Erlang/OTP)
  3. Date: Thu, 13 Jan 2013 13:40:11 GMT
  4. Content-Type: application/json
  5. Content-Length: 227
  6. Cache-Control: must-revalidate
  • Content-type

Specifies the content type of the information being supplied within therequest. The specification uses MIME type specifications. For the majority ofrequests this will be JSON (application/json). For some settings the MIMEtype will be plain text. When uploading attachments it should be thecorresponding MIME type for the attachment or binary(application/octet-stream).

The use of the Content-type on a request is highly recommended.

11.1.2.2. Response Headers

Response headers are returned by the server when sending back content andinclude a number of different header fields, many of which are standard HTTPresponse header and have no significance to CouchDB operation. The list ofresponse headers important to CouchDB are listed below.

  • Cache-control

The cache control HTTP response header provides a suggestion for clientcaching mechanisms on how to treat the returned information. CouchDBtypically returns the must-revalidate, which indicates that theinformation should be revalidated if possible. This is used to ensure thatthe dynamic nature of the content is correctly updated.

  • Content-length

The length (in bytes) of the returned content.

  • Content-type

Specifies the MIME type of the returned data. For most request, the returnedMIME type is text/plain. All text is encoded in Unicode (UTF-8), and thisis explicitly stated in the returned Content-type, astext/plain;charset=utf-8.

  • Etag

The Etag HTTP header field is used to show the revision for a document,or a view.

ETags have been assigned to a map/reduce group (the collection of views in asingle design document). Any change to any of the indexes for those viewswould generate a new ETag for all view URLs in a single design doc, even ifthat specific view’s results had not changed.

Each _view URL has its own ETag which only gets updated when changes aremade to the database that effect that index. If the index for that specificview does not change, that view keeps the original ETag head (thereforesending back 304 - Not Modified more often).

  • Transfer-Encoding

If the response uses an encoding, then it is specified in this header field.

Transfer-Encoding: chunked means that the response is sent in parts, amethod known as chunked transfer encoding. This is used when CouchDB doesnot know beforehand the size of the data it will send (for example,the changes feed).

11.1.3. JSON Basics

The majority of requests and responses to CouchDB use the JavaScript ObjectNotation (JSON) for formatting the content and structure of the data andresponses.

JSON is used because it is the simplest and easiest solution for working withdata within a web browser, as JSON structures can be evaluated and used asJavaScript objects within the web browser environment. JSON also integrateswith the server-side JavaScript used within CouchDB.

JSON supports the same basic types as supported by JavaScript, these are:

  • Array - a list of values enclosed in square brackets. For example:
  1. ["one", "two", "three"]
  • Boolean - a true or false value. You can use these strings directly.For example:
  1. { "value": true}
  • Number - an integer or floating-point number.

  • Object - a set of key/value pairs (i.e. an associative array, or hash). Thekey must be a string, but the value can be any of the supported JSON values.For example:

  1. {
  2. "servings" : 4,
  3. "subtitle" : "Easy to make in advance, and then cook when ready",
  4. "cooktime" : 60,
  5. "title" : "Chicken Coriander"
  6. }

In CouchDB, the JSON object is used to represent a variety of structures,including the main CouchDB document.

  • String - this should be enclosed by double-quotes and supports Unicodecharacters and backslash escaping. For example:
  1. "A String"

Parsing JSON into a JavaScript object is supported through the JSON.parse()function in JavaScript, or through various libraries that will perform theparsing of the content into a JavaScript object for you. Libraries for parsingand generating JSON are available in many languages, including Perl, Python,Ruby, Erlang and others.

Warning

Care should be taken to ensure that your JSON structures are valid,invalid structures will cause CouchDB to return an HTTP status code of 500(server error).

11.1.3.1. Number Handling

Developers and users new to computer handling of numbers often encountersurprises when expecting that a number stored in JSON format does notnecessarily return as the same number as compared character by character.

Any numbers defined in JSON that contain a decimal point or exponent will bepassed through the Erlang VM’s idea of the “double” data type. Any numbers thatare used in views will pass through the view server’s idea of a number (thecommon JavaScript case means even integers pass through a double due toJavaScript’s definition of a number).

Consider this document that we write to CouchDB:

  1. {
  2. "_id":"30b3b38cdbd9e3a587de9b8122000cff",
  3. "number": 1.1
  4. }

Now let’s read that document back from CouchDB:

  1. {
  2. "_id":"30b3b38cdbd9e3a587de9b8122000cff",
  3. "_rev":"1-f065cee7c3fd93aa50f6c97acde93030",
  4. "number":1.1000000000000000888
  5. }

What happens is CouchDB is changing the textual representation of theresult of decoding what it was given into some numerical format. In mostcases this is an IEEE 754 double precision floating point number whichis exactly what almost all other languages use as well.

What Erlang does a bit differently than other languages is that it does notattempt to pretty print the resulting output to use the shortest number ofcharacters. For instance, this is why we have this relationship:

  1. ejson:encode(ejson:decode(<<"1.1">>)).
  2. <<"1.1000000000000000888">>

What can be confusing here is that internally those two formats decode into thesame IEEE-754 representation. And more importantly, it will decode into afairly close representation when passed through all major parsers that we knowabout.

While we’ve only been discussing cases where the textual representationchanges, another important case is when an input value contains more precisionthan can actually represented in a double. (You could argue that this case isactually “losing” data if you don’t accept that numbers are stored in doubles).

Here’s a log for a couple of the more common JSON libraries that happen to beon the author’s machine:

Ejson (CouchDB’s current parser) at CouchDB sha 168a663b:

  1. $ ./utils/run -i
  2. Erlang R14B04 (erts-5.8.5) [source] [64-bit] [smp:2:2] [rq:2]
  3. [async-threads:4] [hipe] [kernel-poll:true]
  4.  
  5. Eshell V5.8.5 (abort with ^G)
  6. 1> ejson:encode(ejson:decode(<<"1.01234567890123456789012345678901234567890">>)).
  7. <<"1.0123456789012346135">>
  8. 2> F = ejson:encode(ejson:decode(<<"1.01234567890123456789012345678901234567890">>)).
  9. <<"1.0123456789012346135">>
  10. 3> ejson:encode(ejson:decode(F)).
  11. <<"1.0123456789012346135">>

Node:

  1. $ node -v
  2. v0.6.15
  3. $ node
  4. JSON.stringify(JSON.parse("1.01234567890123456789012345678901234567890"))
  5. '1.0123456789012346'
  6. var f = JSON.stringify(JSON.parse("1.01234567890123456789012345678901234567890"))
  7. undefined
  8. JSON.stringify(JSON.parse(f))
  9. '1.0123456789012346'

Python:

  1. $ python
  2. Python 2.7.2 (default, Jun 20 2012, 16:23:33)
  3. [GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin
  4. Type "help", "copyright", "credits" or "license" for more information.
  5. import json
  6. json.dumps(json.loads("1.01234567890123456789012345678901234567890"))
  7. '1.0123456789012346'
  8. f = json.dumps(json.loads("1.01234567890123456789012345678901234567890"))
  9. json.dumps(json.loads(f))
  10. '1.0123456789012346'

Ruby:

  1. $ irb --version
  2. irb 0.9.5(05/04/13)
  3. require 'JSON'
  4. => true
  5. JSON.dump(JSON.load("[1.01234567890123456789012345678901234567890]"))
  6. => "[1.01234567890123]"
  7. f = JSON.dump(JSON.load("[1.01234567890123456789012345678901234567890]"))
  8. => "[1.01234567890123]"
  9. JSON.dump(JSON.load(f))
  10. => "[1.01234567890123]"

Note

A small aside on Ruby, it requires a top level object or array, so I justwrapped the value. Should be obvious it doesn’t affect the result ofparsing the number though.

Spidermonkey:

  1. $ js -h 2>&1 | head -n 1
  2. JavaScript-C 1.8.5 2011-03-31
  3. $ js
  4. js> JSON.stringify(JSON.parse("1.01234567890123456789012345678901234567890"))
  5. "1.0123456789012346"
  6. js> var f = JSON.stringify(JSON.parse("1.01234567890123456789012345678901234567890"))
  7. js> JSON.stringify(JSON.parse(f))
  8. "1.0123456789012346"

As you can see they all pretty much behave the same except for Ruby actuallydoes appear to be losing some precision over the other libraries.

The astute observer will notice that ejson (the CouchDB JSON library) reportedan extra three digits. While its tempting to think that this is due to someinternal difference, its just a more specific case of the 1.1 input asdescribed above.

The important point to realize here is that a double can only hold a finitenumber of values. What we’re doing here is generating a string that when passedthrough the “standard” floating point parsing algorithms (ie, strtod) willresult in the same bit pattern in memory as we started with. Or, slightlydifferent, the bytes in a JSON serialized number are chosen such that theyrefer to a single specific value that a double can represent.

The important point to understand is that we’re mapping from one infinite setonto a finite set. An easy way to see this is by reflecting on this:

  1. 1.0 == 1.00 == 1.000 = 1.(infinite zeros)

Obviously a computer can’t hold infinite bytes so we have to decimate ourinfinitely sized set to a finite set that can be represented concisely.

The game that other JSON libraries are playing is merely:

“How few characters do I have to use to select this specific value for adouble”

And that game has lots and lots of subtle details that are difficult toduplicate in C without a significant amount of effort (it took Python over ayear to get it sorted with their fancy build systems that automatically run ona number of different architectures).

Hopefully we’ve shown that CouchDB is not doing anything “funky” by changinginput. Its behaving the same as any other common JSON library does, its justnot pretty printing its output.

On the other hand, if you actually are in a position where an IEEE-754 doubleis not a satisfactory data type for your numbers, then the answer as has beenstated is to not pass your numbers through this representation. In JSON this isaccomplished by encoding them as a string or by using integer types (althoughinteger types can still bite you if you use a platform that has a differentinteger representation than normal, ie, JavaScript).

Further information can be found easily, including theFloating Point Guide, and David Goldberg’s Reference.

Also, if anyone is really interested in changing this behavior, we’re all earsfor contributions to jiffy (which is theoretically going to replace ejsonwhen we get around to updating the build system). The places we’ve looked forinspiration are TCL and Python. If you know a decent implementation of thisfloat printing algorithm give us a holler.

11.1.4. HTTP Status Codes

With the interface to CouchDB working through HTTP, error codes and statusesare reported using a combination of the HTTP status code number, andcorresponding data in the body of the response data.

A list of the error codes returned by CouchDB, and generic descriptions of therelated errors are provided below. The meaning of different status codes forspecific request types are provided in the corresponding API call reference.

  • 200 - OK

Request completed successfully.

  • 201 - Created

Document created successfully.

  • 202 - Accepted

Request has been accepted, but the corresponding operation may not havecompleted. This is used for background operations, such as databasecompaction.

  • 304 - Not Modified

The additional content requested has not been modified. This is used with theETag system to identify the version of information returned.

  • 400 - Bad Request

Bad request structure. The error can indicate an error with the request URL,path or headers. Differences in the supplied MD5 hash and content alsotrigger this error, as this may indicate message corruption.

  • 401 - Unauthorized

The item requested was not available using the supplied authorization, orauthorization was not supplied.

  • 403 - Forbidden

The requested item or operation is forbidden.

  • 404 - Not Found

The requested content could not be found. The content will include furtherinformation, as a JSON object, if available. The structure will contain twokeys, error and reason. For example:

  1. {"error":"not_found","reason":"no_db_file"}
  • 405 - Method Not Allowed

A request was made using an invalid HTTP request type for the URL requested.For example, you have requested a PUT when a POST is required. Errorsof this type can also triggered by invalid URL strings.

  • 406 - Not Acceptable

The requested content type is not supported by the server.

  • 409 - Conflict

Request resulted in an update conflict.

  • 412 - Precondition Failed

The request headers from the client and the capabilities of the server do notmatch.

  • 413 - Request Entity Too Large

A document exceeds the configured couchdb/max_document_sizevalue or the entire request exceeds thehttpd/max_http_request_size value.

  • 415 - Unsupported Media Type

The content types supported, and the content type of the information beingrequested or submitted indicate that the content type is not supported.

  • 416 - Requested Range Not Satisfiable

The range specified in the request header cannot be satisfied by the server.

  • 417 - Expectation Failed

When sending documents in bulk, the bulk load operation failed.

  • 500 - Internal Server Error

The request was invalid, either because the supplied JSON was invalid, orinvalid information was supplied as part of the request.

原文: http://docs.couchdb.org/en/stable/api/basics.html