You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by de...@apache.org on 2013/10/01 15:46:24 UTC

[14/50] [abbrv] git commit: updated refs/heads/replicator-redesign to 066d69b

Import introduction to the API from Guide to CouchDB.

http://guide.couchdb.org/draft/api.html


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/360381ac
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/360381ac
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/360381ac

Branch: refs/heads/replicator-redesign
Commit: 360381ac07ede47ae26e80be17dcf3f75ce23ef5
Parents: 5562be1
Author: Alexander Shorin <kx...@apache.org>
Authored: Sat Sep 7 20:44:09 2013 +0400
Committer: Alexander Shorin <kx...@apache.org>
Committed: Fri Sep 27 22:01:48 2013 +0400

----------------------------------------------------------------------
 share/doc/build/Makefile.am   |   3 +
 share/doc/src/intro/api.rst   | 784 +++++++++++++++++++++++++++++++++++++
 share/doc/src/intro/index.rst |   5 +
 3 files changed, 792 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/360381ac/share/doc/build/Makefile.am
----------------------------------------------------------------------
diff --git a/share/doc/build/Makefile.am b/share/doc/build/Makefile.am
index 16ed5d6..bc4af7b 100644
--- a/share/doc/build/Makefile.am
+++ b/share/doc/build/Makefile.am
@@ -109,6 +109,7 @@ html_files = \
     html/_sources/install/mac.txt \
     html/_sources/install/unix.txt \
     html/_sources/install/windows.txt \
+    html/_sources/intro/api.txt \
     html/_sources/intro/consistency.txt \
     html/_sources/intro/curl.txt \
     html/_sources/intro/futon.txt \
@@ -222,6 +223,7 @@ html_files = \
     html/install/mac.html \
     html/install/unix.html \
     html/install/windows.html \
+    html/intro/api.html \
     html/intro/consistency.html \
     html/intro/curl.html \
     html/intro/futon.html \
@@ -357,6 +359,7 @@ src_files = \
     ../src/install/mac.rst \
     ../src/install/unix.rst \
     ../src/install/windows.rst \
+    ../src/intro/api.rst \
     ../src/intro/consistency.rst \
     ../src/intro/curl.rst \
     ../src/intro/futon.rst \

http://git-wip-us.apache.org/repos/asf/couchdb/blob/360381ac/share/doc/src/intro/api.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/intro/api.rst b/share/doc/src/intro/api.rst
new file mode 100644
index 0000000..f617df0
--- /dev/null
+++ b/share/doc/src/intro/api.rst
@@ -0,0 +1,784 @@
+.. Licensed under the Apache License, Version 2.0 (the "License"); you may not
+.. use this file except in compliance with the License. You may obtain a copy of
+.. the License at
+..
+..   http://www.apache.org/licenses/LICENSE-2.0
+..
+.. Unless required by applicable law or agreed to in writing, software
+.. distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+.. WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+.. License for the specific language governing permissions and limitations under
+.. the License.
+
+.. default-domain:: http
+
+.. _intro/api:
+
+============
+The Core API
+============
+
+This chapter explores the CouchDB in minute detail. It shows all the
+nitty-gritty and clever bits. We show you best practices and guide you around
+common pitfalls.
+
+We start out by revisiting the basic operations we ran in the last chapter,
+looking behind the scenes. We also show what Futon needs to do behind its
+user interface to give us the nice features we saw earlier.
+
+This chapter is both an introduction to the core CouchDB API as well as a
+reference. If you can't remember how to run a particular request or why some
+parameters are needed, you can always come back here and look things up (we
+are probably the heaviest users of this chapter).
+
+While explaining the API bits and pieces, we sometimes need to take a larger
+detour to explain the reasoning for a particular request. This is a good
+opportunity for us to tell you why CouchDB works the way it does.
+
+The API can be subdivided into the following sections. We'll explore them
+individually:
+
+.. contents::
+   :depth: 1
+   :local:
+
+
+Server
+======
+
+This one is basic and simple. It can serve as a sanity check to see if
+CouchDB is running at all. It can also act as a safety guard for libraries
+that require a certain version of CouchDB. We're using the `curl`_ utility
+again::
+
+  curl http://127.0.0.1:5984/
+
+CouchDB replies, all excited to get going:
+
+.. code-block:: javascript
+
+  {
+    "couchdb": "Welcome",
+    "uuid": "85fb71bf700c17267fef77535820e371",
+    "vendor": {
+        "name": "The Apache Software Foundation",
+        "version": "1.4.0"
+    },
+    "version": "1.4.0"
+  }
+
+You get back a JSON string, that, if parsed into a native object or data
+structure of your programming language, gives you access to the welcome
+string and version information.
+
+This is not terribly useful, but it illustrates nicely the way CouchDB
+behaves. You send an HTTP request and you receive a JSON string in the HTTP
+response as a result.
+
+.. _curl: http://curl.haxx.se/
+
+
+Databases
+=========
+
+Now let's do something a little more useful: *create databases*.
+For the strict, CouchDB is a *database management system* (DMS). That means it
+can hold multiple databases. A database is a bucket that holds "related data".
+We'll explore later what that means exactly. In practice, the terminology is
+overlapping -- often people refer to a DMS as "a database" and also a database
+within the DMS as "a database." We might follow that slight oddity, so don't
+get confused by it. In general, it should be clear from the context if we are
+talking about the whole of CouchDB or a single database within CouchDB.
+
+Now let's make one! We want to store our favorite music albums,
+and we creatively give our database the name albums. Note that we're now
+using the ``-X`` option again to tell curl to send a :method:`PUT` request
+instead of the default :method:`GET` request::
+
+  curl -X PUT http://127.0.0.1:5984/albums
+
+CouchDB replies:
+
+.. code-block:: javascript
+
+  {"ok":true}
+
+That's it. You created a database and CouchDB told you that all went well.
+What happens if you try to create a database that already exists? Let's try
+to create that database again::
+
+  curl -X PUT http://127.0.0.1:5984/albums
+
+CouchDB replies:
+
+.. code-block:: javascript
+
+  {"error":"file_exists","reason":"The database could not be created, the file already exists."}
+
+We get back an error. This is pretty convenient. We also learn a little bit
+about how CouchDB works. CouchDB stores each database in a single file.
+Very simple.
+
+Let's create another database, this time with curl's ``-v`` (for "verbose")
+option. The verbose option tells curl to show us not only the essentials -- 
+the HTTP response body -- but all the underlying request and response details::
+
+  curl -vX PUT http://127.0.0.1:5984/albums-backup
+
+curl elaborates::
+
+  * About to connect() to 127.0.0.1 port 5984 (#0)
+  *   Trying 127.0.0.1... connected
+  * Connected to 127.0.0.1 (127.0.0.1) port 5984 (#0)
+  > PUT /albums-backup HTTP/1.1
+  > User-Agent: curl/7.16.3 (powerpc-apple-darwin9.0) libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3
+  > Host: 127.0.0.1:5984
+  > Accept: */*
+  >
+  < HTTP/1.1 201 Created
+  < Server: CouchDB/0.9.0 (Erlang OTP/R12B)
+  < Date: Sun, 05 Jul 2009 22:48:28 GMT
+  < Content-Type: text/plain;charset=utf-8
+  < Content-Length: 12
+  < Cache-Control: must-revalidate
+  <
+  {"ok":true}
+  * Connection #0 to host 127.0.0.1 left intact
+  * Closing connection #0
+
+What a mouthful. Let's step through this line by line to understand what's
+going on and find out what's important. Once you've seen this output a few
+times, you'll be able to spot the important bits more easily.
+
+::
+
+  * About to connect() to 127.0.0.1 port 5984 (#0)
+
+This is curl telling us that it is going to establish a TCP connection to the
+CouchDB server we specified in our request URI. Not at all important,
+except when debugging networking issues.
+
+::
+
+  *   Trying 127.0.0.1... connected
+  * Connected to 127.0.0.1 (127.0.0.1) port 5984 (#0)
+
+curl tells us it successfully connected to CouchDB. Again,
+not important if you aren't trying to find problems with your network.
+
+The following lines are prefixed with ``>`` and ``<`` characters.
+The ``>`` means the line was sent to CouchDB verbatim (without the actual
+``>``). The ``<`` means the line was sent back to curl by CouchDB.
+
+::
+
+  > PUT /albums-backup HTTP/1.1
+
+This initiates an HTTP request. Its *method* is :method:`PUT`, the *URI* is
+``/albums-backup``, and the HTTP version is ``HTTP/1.1``. There is also 
+``HTTP/1.0``, which is simpler in some cases, but for all practical reasons 
+you should be using ``HTTP/1.1``.
+
+Next, we see a number of *request headers*. These are used to provide
+additional details about the request to CouchDB.
+
+::
+
+  > User-Agent: curl/7.16.3 (powerpc-apple-darwin9.0) libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3
+
+The User-Agent header tells CouchDB which piece of client software is doing
+the HTTP request. We don't learn anything new: it's curl. This header is
+often useful in web development when there are known errors in client
+implementations that a server might want to prepare the response for.
+It also helps to determine which platform a user is on. This information 
+can be used for technical and statistical reasons. For CouchDB, the 
+:header:`User-Agent` header is irrelevant.
+
+::
+
+  > Host: 127.0.0.1:5984
+
+The :header:`Host` header is required by ``HTTP 1.1``. It tells the server
+the hostname that came with the request.
+
+::
+
+  > Accept: */*
+
+The :header:`Accept` header tells CouchDB that curl accepts any media type.
+We'll look into why this is useful a little later.
+
+::
+
+  >
+
+An empty line denotes that the request headers are now finished and the rest
+of the request contains data we're sending to the server. In this case,
+we're not sending any data, so the rest of the curl output is dedicated to
+the HTTP response.
+
+::
+
+  < HTTP/1.1 201 Created
+
+The first line of CouchDB's HTTP response includes the HTTP version
+information (again, to acknowledge that the requested version could be
+processed), an HTTP *status code*, and a *status code message*.
+Different requests trigger different response codes. There's a whole range of
+them telling the client (curl in our case) what effect the request had on the
+server. Or, if an error occurred, what kind of error. :rfc:`2616` (the HTTP 1.1
+specification) defines clear behavior for response codes. CouchDB fully
+follows the RFC.
+
+The :statuscode:`201` status code tells the client that the resource 
+the request was made against was successfully created. No surprise here,
+but if you remember that we got an error message when we tried to create this
+database twice, you now know that this response could include a different
+response code. Acting upon responses based on response codes is a common
+practice. For example, all response codes of :statuscode:`400` or larger 
+tell you that some error occurred. If you want to shortcut your logic and 
+immediately deal with the error, you could just check a >= ``400`` response 
+code.
+
+::
+
+  < Server: CouchDB/0.10.1 (Erlang OTP/R13B)
+
+The :header:`Server` header is good for diagnostics. It tells us which 
+CouchDB version and which underlying Erlang version we are talking to. 
+In general, you can ignore this header, but it is good to know it's there if 
+you need it.
+
+::
+
+  < Date: Sun, 05 Jul 2009 22:48:28 GMT
+
+The :header:`Date` header tells you the time of the server. Since client 
+and server time are not necessarily synchronized, this header is purely 
+informational. You shouldn't build any critical application logic on top 
+of this!
+
+::
+
+  < Content-Type: text/plain;charset=utf-8
+
+The :header:`Content-Type` header tells you which MIME type 
+the HTTP response body is and its encoding. We already know CouchDB returns 
+JSON strings. The appropriate :header:`Content-Type` header is 
+:mimetype:`application/json`. Why do we see :mimetype:`text/plain`? 
+This is where pragmatism wins over purity. Sending an 
+:mimetype:`application/json` :header:`Content-Type` header will make 
+a browser offer you the returned JSON for download instead of 
+just displaying it. Since it is extremely useful to be able to test CouchDB 
+from a browser, CouchDB sends a :mimetype:`text/plain` content type, so all 
+browsers will display the JSON as text.
+
+.. note::
+
+  There are some extensions that make your browser JSON-aware,
+  but they are not installed by default. For more information, look at
+  the popular `JSONView`_ extension, available for both Firefox and Chrome.
+
+  .. _JSONView: http://jsonview.com/
+
+Do you remember the :header:`Accept` request header and how it is set to 
+``\*/\* -> */*`` to express interest in any MIME type? If you send ``Accept:
+application/json`` in your request, CouchDB knows that you can deal with a pure 
+JSON response with the proper :header:`Content-Type` header and will 
+use it instead of :mimetype:`text/plain`.
+
+::
+
+  < Content-Length: 12
+
+The :header:`Content-Length` header simply tells us how many bytes 
+the response body has.
+
+::
+
+  < Cache-Control: must-revalidate
+
+This :header:`Cache-Control` header tells you, or any proxy server between 
+CouchDB and you, not to cache this response.
+
+::
+
+  <
+
+This empty line tells us we're done with the response headers and what
+follows now is the response body.
+
+.. code-block:: javascript
+
+  {"ok":true}
+
+We've seen this before.
+
+::
+
+  * Connection #0 to host 127.0.0.1 left intact
+  * Closing connection #0
+
+The last two lines are curl telling us that it kept the TCP connection it
+opened in the beginning open for a moment, but then closed it after it
+received the entire response.
+
+Throughout the book, we'll show more requests with the ``-v`` option,
+but we'll omit some of the headers we've seen here and include only those
+that are important for the particular request.
+
+Creating databases is all fine, but how do we get rid of one? Easy -- just
+change the HTTP method::
+
+  > curl -vX DELETE http://127.0.0.1:5984/albums-backup
+
+This deletes a CouchDB database. The request will remove the file that the
+database contents are stored in. There is no *"Are you sure?"* safety net or
+any *"Empty the trash"* magic you've got to do to delete a database. Use this
+command with care. Your data will be deleted without a chance to bring it
+back easily if you don't have a backup copy.
+
+This section went knee-deep into HTTP and set the stage for discussing the
+rest of the core CouchDB API. Next stop: documents.
+
+
+Documents
+=========
+
+.. _GUID: http://en.wikipedia.org/wiki/Globally_unique_identifier
+.. _UUID: http://en.wikipedia.org/wiki/Universally_unique_identifier
+
+Documents are CouchDB's central data structure. The idea behind a document
+is, unsurprisingly, that of a real-world document -- a sheet of paper such as
+an invoice, a recipe, or a business card. We already learned that CouchDB uses
+the JSON format to store documents. Let's see how this storing works at the
+lowest level.
+
+Each document in CouchDB has an *ID*. This ID is unique per database. You are
+free to choose any string to be the ID, but for best results we recommend a
+`UUID`_ (or `GUID`_), i.e., a Universally (or Globally) Unique IDentifier.
+UUIDs are random numbers that have such a low collision probability that
+everybody can make thousands of UUIDs a minute for millions of years without
+ever creating a duplicate. This is a great way to ensure two independent people
+cannot create two different documents with the same ID. Why should you care
+what somebody else is doing? For one, that somebody else could be you at a
+later time or on a different computer; secondly, CouchDB replication lets you
+share documents with others and using UUIDs ensures that it all works.
+But more on that later; let's make some documents::
+
+  curl -X PUT http://127.0.0.1:5984/albums/6e1295ed6c29495e54cc05947f18c8af -d '{"title":"There is Nothing Left to Lose","artist":"Foo Fighters"}'
+
+CouchDB replies:
+
+.. code-block:: javascript
+
+  {"ok":true,"id":"6e1295ed6c29495e54cc05947f18c8af","rev":"1-2902191555"}
+  
+The curl command appears complex, but let's break it down. 
+First, ``-X PUT`` tells curl to make a :method:`PUT` request. 
+It is followed by the URL that specifies your CouchDB IP address and port. 
+The resource part of the URL ``/albums/6e1295ed6c29495e54cc05947f18c8af``
+specifies the location of a document inside our albums database. 
+The wild collection of numbers and characters is a UUID. This UUID is your 
+document's ID. Finally, the ``-d`` flag tells curl to use the following 
+string as the body for the :method:`PUT` request. The string is a simple JSON
+structure including ``title`` and ``artist`` attributes with their respective
+values.
+
+.. note::
+
+  If you don't have a UUID handy, you can ask CouchDB to give you one (in fact,
+  that is what we did just now without showing you). Simply send a
+  :get:`/_uuids` request::
+
+    curl -X GET http://127.0.0.1:5984/_uuids
+
+  CouchDB replies:
+
+  .. code-block:: javascript
+
+    {"uuids":["6e1295ed6c29495e54cc05947f18c8af"]}
+  
+  VoilĂ , a UUID. If you need more than one, you can pass in the ``?count=10`` HTTP
+  parameter to request 10 UUIDs, or really, any number you need.
+
+To double-check that CouchDB isn't lying about having saved your document (it
+usually doesn't), try to retrieve it by sending a GET request::
+
+  curl -X GET http://127.0.0.1:5984/albums/6e1295ed6c29495e54cc05947f18c8af
+ 
+We hope you see a pattern here. Everything in CouchDB has an address, a URI,
+and you use the different HTTP methods to operate on these URIs.
+
+CouchDB replies:
+
+.. code-block:: javascript
+
+  {"_id":"6e1295ed6c29495e54cc05947f18c8af","_rev":"1-2902191555","title":"There is Nothing Left to Lose","artist":"Foo Fighters"}
+
+This looks a lot like the document you asked CouchDB to save, which is good.
+But you should notice that CouchDB added two fields to your JSON structure.
+The first is ``_id``, which holds the UUID we asked CouchDB to save our document
+under. We always know the ID of a document if it is included, which is very
+convenient.
+
+The second field is ``_rev``. It stands for *revision*.
+
+Revisions
+---------
+
+If you want to change a document in CouchDB, you don't tell it to go and find
+a field in a specific document and insert a new value. Instead, you load 
+the full document out of CouchDB, make your changes in the JSON structure 
+(or object, when you are doing actual programming), and save the entire new 
+revision (or version) of that document back into CouchDB. Each revision is 
+identified by a new ``_rev`` value.
+
+If you want to update or delete a document, CouchDB expects you to include
+the ``_rev`` field of the revision you wish to change. When CouchDB accepts
+the change, it will generate a new revision number. This mechanism ensures that,
+in case somebody else made a change without you knowing before you got to
+request the document update, CouchDB will not accept your update because you
+are likely to overwrite data you didn't know existed. Or simplified: whoever
+saves a change to a document first, wins. Let's see what happens if we don't
+provide a ``_rev`` field (which is equivalent to providing a outdated value)::
+
+  curl -X PUT http://127.0.0.1:5984/albums/6e1295ed6c29495e54cc05947f18c8af \
+       -d '{"title":"There is Nothing Left to Lose","artist":"Foo Fighters","year":"1997"}'
+
+CouchDB replies:
+
+.. code-block:: javascript
+
+  {"error":"conflict","reason":"Document update conflict."}
+  
+If you see this, add the latest revision number of your document to the JSON
+structure::
+
+  curl -X PUT http://127.0.0.1:5984/albums/6e1295ed6c29495e54cc05947f18c8af \
+       -d '{"_rev":"1-2902191555","title":"There is Nothing Left to Lose","artist":"Foo Fighters","year":"1997"}'
+
+Now you see why it was handy that CouchDB returned that ``_rev`` when we made 
+the initial request. CouchDB replies:
+
+.. code-block:: javascript
+
+  {"ok":true,"id":"6e1295ed6c29495e54cc05947f18c8af","rev":"2-8aff9ee9d06671fa89c99d20a4b3ae"}
+  
+CouchDB accepted your write and also generated a new revision number. 
+The revision number is the *MD5 hash* of the transport representation of a
+document with an ``N-`` prefix denoting the number of times a document got 
+updated. This is useful for replication. See :ref:`replication/conflicts` for
+more information.
+
+There are multiple reasons why CouchDB uses this revision system,
+which is also called Multi-Version Concurrency Control (`MVCC`_). They all work
+hand-in-hand, and this is a good opportunity to explain some of them.
+
+.. _MVCC: http://en.wikipedia.org/wiki/Multiversion_concurrency_control
+
+One of the aspects of the HTTP protocol that CouchDB uses is that it is
+stateless. What does that mean? When talking to CouchDB you need to make
+requests. Making a request includes opening a network connection to CouchDB,
+exchanging bytes, and closing the connection. This is done every time you
+make a request. Other protocols allow you to open a connection, exchange bytes,
+keep the connection open, exchange more bytes later -- maybe depending on the
+bytes you exchanged at the beginning -- and eventually close the connection.
+Holding a connection open for later use requires the server to do extra work.
+One common pattern is that for the lifetime of a connection, the client has
+a consistent and static view of the data on the server. Managing huge amounts
+of parallel connections is a significant amount of work. HTTP connections are
+usually short-lived, and making the same guarantees is a lot easier.
+As a result, CouchDB can handle many more concurrent connections.
+
+Another reason CouchDB uses MVCC is that this model is simpler conceptually
+and, as a consequence, easier to program. CouchDB uses less code to make this
+work, and less code is always good because the ratio of defects per lines of
+code is static.
+
+The revision system also has positive effects on replication and storage
+mechanisms, but we'll explore these later in the book.
+
+.. warning::
+
+  The terms *version* and *revision* might sound familiar (if you are
+  programming without version control, drop this book right now and start
+  learning one of the popular systems). Using new versions for document changes
+  works a lot like version control, but there's an important difference:
+  **CouchDB does not guarantee that older versions are kept around**.
+
+
+Documents in Detail
+-------------------
+
+Now let's have a closer look at our document creation requests with the curl
+``-v`` flag that was helpful when we explored the database API earlier.
+This is also a good opportunity to create more documents that we can use in
+later examples.
+
+We'll add some more of our favorite music albums. Get a fresh UUID from the
+``/_uuids`` resource. If you don't remember how that works, you can look it up
+a few pages back.
+
+::
+
+  curl -vX PUT http://127.0.0.1:5984/albums/70b50bfa0a4b3aed1f8aff9e92dc16a0 \
+       -d '{"title":"Blackened Sky","artist":"Biffy Clyro","year":2002}'
+
+.. note::
+
+  By the way, if you happen to know more information about your favorite
+  albums, don't hesitate to add more properties. And don't worry about not
+  knowing all the information for all the albums. CouchDB's schema-less
+  documents can contain whatever you know. After all, you should relax and not
+  worry about data.
+
+Now with the ``-v`` option, CouchDB's reply (with only the important bits shown)
+looks like this::
+
+  > PUT /albums/70b50bfa0a4b3aed1f8aff9e92dc16a0 HTTP/1.1
+  >
+  < HTTP/1.1 201 Created
+  < Location: http://127.0.0.1:5984/albums/70b50bfa0a4b3aed1f8aff9e92dc16a0
+  < ETag: "1-e89c99d29d06671fa0a4b3ae8aff9e"
+  <
+  {"ok":true,"id":"70b50bfa0a4b3aed1f8aff9e92dc16a0","rev":"1-e89c99d29d06671fa0a4b3ae8aff9e"}
+
+We're getting back the :statuscode:`201` HTTP status code in the response
+headers, as we saw earlier when we created a database. The :header:`Location`
+header gives us a full URL to our newly created document. And there's a new
+header. An :header:`ETag` in HTTP-speak identifies a specific version of a
+resource. In this case, it identifies a specific version (the first one) of our
+new document. Sound familiar? Yes, conceptually, an :header:`ETag` is the same
+as a CouchDB document revision number, and it shouldn't come as a surprise that
+CouchDB uses revision numbers for ETags. ETags are useful for caching
+infrastructures.
+
+
+Attachments
+-----------
+
+CouchDB documents can have attachments just like an email message can have
+attachments. An attachment is identified by a name and includes its MIME type
+(or :header:`Content-Type`) and the number of bytes the attachment
+contains. Attachments can be any data. It is easiest to think about attachments
+as files attached to a document. These files can be text, images, Word
+documents, music, or movie files. Let's make one.
+
+Attachments get their own URL where you can upload data. Say we want to add
+the album artwork to the ``6e1295ed6c29495e54cc05947f18c8af`` document
+(*"There is Nothing Left to Lose"*), and let's also say the artwork is in a file
+artwork `.jpg` in the current directory::
+
+  curl -vX PUT http://127.0.0.1:5984/albums/6e1295ed6c29495e54cc05947f18c8af/artwork.jpg?rev=2-2739352689 \
+       --data-binary @artwork.jpg -H "Content-Type:image/jpg"
+
+.. note::
+
+  The ``--data-binary`` ``@`` option tells curl to read a file's contents into 
+  the HTTP request body. We're using the ``-H`` option to tell CouchDB that 
+  we're uploading a JPEG file. CouchDB will keep this information around and 
+  will send the appropriate header when requesting this attachment; in case of 
+  an image like this, a browser will render the image instead of offering you 
+  the data for download. This will come in handy later. Note that you need 
+  to provide the current revision number of the document you're attaching 
+  the artwork to, just as if you would update the document. Because, after all,
+  attaching some data is changing the document.
+
+You should now see your artwork image if you point your browser to 
+http://127.0.0.1:5984/albums/6e1295ed6c29495e54cc05947f18c8af/artwork.jpg
+
+If you request the document again, you'll see a new member::
+
+  curl http://127.0.0.1:5984/albums/6e1295ed6c29495e54cc05947f18c8af
+
+CouchDB replies:
+
+.. code-block:: javascript
+
+  {
+    "_id": "6e1295ed6c29495e54cc05947f18c8af",
+    "_rev": "3-131533518",
+    "title": "There is Nothing Left to Lose",
+    "artist": "Foo Fighters",
+    "year": "1997",
+    "_attachments": {
+        "artwork.jpg": {
+            "stub": true,
+            "content_type": "image/jpg",
+            "length": 52450
+        }
+    }
+  }
+
+``_attachments`` is a list of keys and values where the values are JSON objects
+containing the attachment metadata. ``stub=true`` tells us that this entry is
+just the metadata. If we use the ``?attachments=true`` HTTP option when 
+requesting this document, we'd get a `Base64`_ encoded string containing the
+attachment data.
+
+.. _Base64: http://en.wikipedia.org/wiki/Base64
+
+We'll have a look at more document request options later as we explore more
+features of CouchDB, such as replication, which is the next topic.
+
+
+Replication
+===========
+
+CouchDB replication is a mechanism to synchronize databases. Much like `rsync`_
+synchronizes two directories locally or over a network, replication synchronizes 
+two databases locally or remotely.
+
+.. _rsync: http://en.wikipedia.org/wiki/Rsync
+
+In a simple :method:`POST` request, you tell CouchDB the *source* and the
+*target* of a replication and CouchDB will figure out which documents and new
+document revisions are on *source* that are not yet on *target*, and will
+proceed  to move the missing documents and revisions over.
+
+We'll take an in-depth look at replication later in the book; in this
+chapter, we'll just show you how to use it.
+
+First, we'll create a target database. Note that CouchDB won't automatically
+create a target database for you, and will return a replication failure if
+the target doesn't exist (likewise for the source, but that mistake isn't as
+easy to make)::
+
+  curl -X PUT http://127.0.0.1:5984/albums-replica
+
+Now we can use the database `albums-replica` as a replication target::
+
+  curl -vX POST http://127.0.0.1:5984/_replicate \
+       -d '{"source":"albums","target":"albums-replica"}' \
+       -H "Content-Type: application/json"
+
+.. note::
+
+  CouchDB supports the option ``"create_target":true`` placed in the JSON POSTed
+  to the :ref:`_replicate <api/server/replicate>` URL. It implicitly creates
+  the target database if it doesn't exist.
+
+CouchDB replies (this time we formatted the output so you can read it more
+easily):
+
+.. code-block:: javascript
+
+  {
+    "history": [
+      {
+        "start_last_seq": 0,
+        "missing_found": 2,
+        "docs_read": 2,
+        "end_last_seq": 5,
+        "missing_checked": 2,
+        "docs_written": 2,
+        "doc_write_failures": 0,
+        "end_time": "Sat, 11 Jul 2009 17:36:21 GMT",
+        "start_time": "Sat, 11 Jul 2009 17:36:20 GMT"
+      }
+    ],
+    "source_last_seq": 5,
+    "session_id": "924e75e914392343de89c99d29d06671",
+    "ok": true
+  }
+  
+CouchDB maintains a *session history* of replications. The response for a
+replication request contains the history entry for this *replication session*.
+It is also worth noting that the request for replication will stay open until
+replication closes. If you have a lot of documents, it'll take a while until
+they are all replicated and you won't get back the replication response
+until all documents are replicated. It is important to note that
+replication replicates the database only as it was at the point in time
+when replication was started. So, any additions, modifications,
+or deletions subsequent to the start of replication will not be replicated.
+
+We'll punt on the details again -- the ``"ok": true`` at the end tells us all 
+went well. If you now have a look at the albums-replica database,
+you should see all the documents that you created in the albums database.
+Neat, eh?
+
+What you just did is called local replication in CouchDB terms. You created a
+local copy of a database. This is useful for backups or to keep snapshots of
+a specific state of your data around for later. You might want to do this
+if you are developing your applications but want to be able to roll back to
+a stable version of your code and data.
+
+There are more types of replication useful in other situations. The source
+and target members of our replication request are actually links (like in
+HTML) and so far we've seen links relative to the server we're working on
+(hence local). You can also specify a remote database as the target::
+
+  curl -vX POST http://127.0.0.1:5984/_replicate \
+       -d '{"source":"albums","target":"http://example.org:5984/albums-replica"}' \
+       -H "Content-Type:application/json"
+
+Using a *local source* and a *remote target* database is called *push
+replication*. We're pushing changes to a remote server.
+
+.. note::
+
+  Since we don't have a second CouchDB server around just yet, we'll just use
+  the absolute address of our single server, but you should be able to infer
+  from this that you can put any remote server in there.
+
+This is great for sharing local changes with remote servers or buddies next
+door.
+
+You can also use a *remote source* and a *local target* to do a *pull
+replication*. This is great for getting the latest changes from a server that
+is used by others::
+
+  curl -vX POST http://127.0.0.1:5984/_replicate \
+       -d '{"source":"http://example.org:5984/albums-replica","target":"albums"}' \
+       -H "Content-Type:application/json"
+
+Finally, you can run remote replication, which is mostly useful for management 
+operations::
+
+  curl -vX POST http://127.0.0.1:5984/_replicate \
+       -d '{"source":"http://example.org:5984/albums","target":"http://example.org:5984/albums-replica"}' \
+       -H"Content-Type: application/json"
+
+.. note::
+
+  **CouchDB and REST**
+
+  CouchDB prides itself on having a `RESTful`_ API, but these replication
+  requests don't look very RESTy to the trained eye. What's up with that?
+  While CouchDB's core database, document, and attachment API are RESTful,
+  not all of CouchDB's API is. The replication API is one example. There are
+  more, as we'll see later in the book.
+
+  Why are there RESTful and non-RESTful APIs mixed up here? Have the developers
+  been too lazy to go REST all the way? Remember, REST is an architectural
+  style that lends itself to certain architectures (such as the CouchDB
+  document API). But it is not a one-size-fits-all. Triggering an event like
+  replication does not make a whole lot of sense in the REST world. It is more
+  like a traditional remote procedure call. And there is nothing wrong with
+  this.
+
+  We very much believe in the "use the right tool for the job" philosophy,
+  and REST does not fit every job. For support, we refer to Leonard Richardson
+  and Sam Ruby who wrote `RESTful Web Services`_ (O'Reilly), as they share our
+  view.
+
+  .. _RESTful: http://en.wikipedia.org/wiki/Representational_state_transfer
+  .. _RESTful Web Services: http://oreilly.com/catalog/9780596529260
+
+
+Wrapping Up
+===========
+
+This is still not the full CouchDB API, but we discussed the essentials in
+great detail. We're going to fill in the blanks as we go. For now, we believe 
+you're ready to start building CouchDB applications.
+
+.. seealso::
+
+  :ref:`Complete HTTP API Reference <api>`:
+
+  - :ref:`Server API Reference <api/server>`
+  - :ref:`Database API Reference <api/database>`
+  - :ref:`Document API Reference <api/document>`
+  - :ref:`Replication API <api/server/replicate>`

http://git-wip-us.apache.org/repos/asf/couchdb/blob/360381ac/share/doc/src/intro/index.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/intro/index.rst b/share/doc/src/intro/index.rst
index 900dca2..a934fae 100644
--- a/share/doc/src/intro/index.rst
+++ b/share/doc/src/intro/index.rst
@@ -37,6 +37,10 @@ consistent <intro/consistency>`. And we care *a lot* about your data.
 CouchDB has a fault-tolerant storage engine that puts the safety of your data
 first.
 
+In this section you'll learn about every basic bit of CouchDB, see upon what
+conceptions and technologies it built and walk through short tutorial that
+teach how to use CouchDB.
+
 .. _distributed scaling: http://en.wikipedia.org/wiki/CAP_theorem
 
 .. toctree::
@@ -46,5 +50,6 @@ first.
    why
    consistency
    tour
+   api
    futon
    curl