couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Apache Wiki <wikidi...@apache.org>
Subject [Couchdb Wiki] Update of "Formatting_with_Show_and_List" by JoanTouzet
Date Fri, 13 Apr 2018 05:53:18 GMT
Dear wiki user,

You have subscribed to a wiki page "Couchdb Wiki" for change notification.

The page "Formatting_with_Show_and_List" has been deleted by JoanTouzet:

https://wiki.apache.org/couchdb/Formatting_with_Show_and_List?action=diff&rev1=33&rev2=34

Comment:
We already ahve the documentation for show/list that we want...the rest is semi-deprecated.

- <<Include(EditTheWiki)>>
  
- = Formatting with Show and List =
- 
- See also the official documentation for the 
- [[http://docs.couchdb.org/en/latest/ddocs.html#show-functions|show]] and 
- [[http://docs.couchdb.org/en/latest/ddocs.html#list-functions|list]] topics.
- 
- <<TableOfContents()>>
- 
- Note that this is only available in CouchDB 0.9 or newer
- 
- The basics of formatting documents using `show` and `list` functions. These functions convert
documents and views, respectively, into non-JSON formats. The rows of each view are processed
individually, which keeps long lists from becoming memory hogs.
- 
- They are designed to be cacheable. CouchDB handles generating Etags for show and list responses.
- 
- Show and list functions are side effect free and idempotent. They can not make additional
HTTP requests against CouchDB. Their purpose is to render JSON documents in other formats.
- 
- == Showing Documents ==
-  . [[http://guide.couchdb.org/draft/show.html|CouchDB Guide section]]
- 
- Show functions are stored in your design document, under the `shows` key. Here's an example
set of show functions:
- 
- {{{#!highlight javascript
- {
-     "_id": "_design/examples",
-     "shows": {
-         "posts": "function(doc, req) { /*...*/ return responseObject;}",
-         "people": "function(doc, req) { /*...*/ }"
-     }
- }
- }}}
- Assuming these functions were in a design document named "`examples`" in a database named
"`db`", they could be queried like this:
- 
- {{{
- GET /db/_design/examples/_show/posts/somedocid
- 
- GET /db/_design/examples/_show/people/otherdocid
- 
- GET /db/_design/examples/_show/people/otherdocid?format=xml&details=true
- }}}
- The `show` function is run with two arguments. The first is the document corresponding to
the requested `docid`, and the second describes the HTTP request's query string, Accept headers,
and other per-request information. The function returns an object describing its HTTP response.
- 
- Example `show` function
- 
- {{{#!highlight javascript
- function(doc, req) {
-   return {
-     body: "Hello World"
-   }
- }
- }}}
- If the show function is queried with document id that has no corresponding document in the
database, `doc` is `null` and the submitted document shows up in `req.id`. This is useful
for creating new documents with a name, like in a wiki.
- 
- If the show function is queried without a document id at all, doc is `null` and `req.id`
is `null`. This is useful for creating new documents where the user specifies the new document
id in a user interface, like in a CMS.
- 
- {{{#!highlight javascript
- function(doc, req) {
-   if(doc) {
-     // regular doc display logic
-   } else { // document not found
-     if(req.id) {
-       // handle unused doc id
-     } else {
-       // handle unspecified doc id
-     }
-   }
- }
- }}}
- The request and response objects are of the same format used by `_external` functions, as
documented in ExternalProcesses.
- 
- Since CouchDB 0.11.0 you can use the `send()` function as explained below in show functions
as well.
- 
- == Listing Views with CouchDB 0.10 and later ==
-  . [[http://guide.couchdb.org/draft/transforming.html|CouchDB Guide section]]
- 
- List functions are stored under the `lists` key of a design document. Here's an example
design doc with list functions, in addition to views:
- 
- {{{#!highlight javascript
- {
-     "_id": "_design/examples",
-     "views" {
-         "posts-by-date": {"map": "function(doc){ /*...*/ }"},
-         "posts-by-tag": {"map": "function(doc){ /*...*/ }"},
-         "people-by-name": {"map": "function(doc) { /*...*/ }"}
-     },
-     "lists": {
-         "index-posts": "function(head, req) { /*...*/ }",
-         "browse-people": "function(head, req) { /*...*/ }"
-     }
- }
- }}}
- These lists are run by querying URLs like:
- 
- {{{
- GET /db/_design/examples/_list/index-posts/posts-by-date?descending=true&limit=10
- 
- GET /db/_design/examples/_list/index-posts/posts-by-tag?key="howto"
- 
- GET /db/_design/examples/_list/browse-people/people-by-name?startkey=["a"]&limit=10
- }}}
- As above, we assume the database is named "db" and the design doc "examples".
- 
- Couchdb 0.10 supports an alternate form of URL which allows you to use a list function and
a view from different design documents.  This is particularly useful when you want to use
a different language for the list and for the view. These URLs are very similar to the above
examples, but instead of the tail portion being the name of the view, the tail portion can
consist of two parts - a design doc name and the name of the view in that second document.
 For example:
- 
- {{{
- GET /db/_design/examples/_list/index-posts/other_ddoc/posts-by-tag?key="howto"
- }}}
- [As above, we assume the database is named "db" and the design doc with the list is named
"examples", while the design doc with the view is "other_ddoc".]
- 
- An Example `list` function
- 
- {{{#!highlight javascript
- function(head, req) {
-   var row;
-   start({
-     "headers": {
-       "Content-Type": "text/html"
-      }
-   });
-   while(row = getRow()) {
-     send(row.value);
-   }
- }
- }}}
- == Listing Views with CouchDB 0.9 ==
- List functions were introduced in CouchDB 0.9 and had different, more complex API. This
API is no longer available after 0.10.
- 
- A list function has a more interesting signature, as it is passed the head of the view on
first invocation, then each row in turn, then called one more time for the tail of the view.
The function should check the `head` and `row` parameters to identify which state it's being
called in; the sequence of calls to `listfn`, for a view with three rows, would look like:
- 
- {{{#!highlight javascript
- listfn(head, null,    req, null    );  // Before the first row: head is non-null
- listfn(null, rows[0], req, row_info);  // First row
- listfn(null, rows[1], req, row_info);  // Subsequent rows...
- listfn(null, rows[2], req, row_info);
- listfn(null, null,    req, row_info);  // After last row: row=null
- }}}
- The `head` parameter -- which is only passed into the first call -- contains an object with
information about the view that is to be iterated over. It's much like the response object
returned from a view query in the CouchDB JavaScript API; useful properties include `total_rows`
and `offset`.
- 
- The `row_info` parameter contains an object with information about the iteration state.
Its properties include:
- 
-  * `row_number` (the current row number)
-  * `first_key` (the first key of the view to be listed)
-  * `prev_key` (the key of the row in the previous iteration)
- 
- Example list function:
- 
- {{{#!highlight javascript
- function(head, row, req, row_info) {
-   if (head) {
-     return "<p>head: "+JSON.stringify(head)+"</p><ul>";
-   } else if (row) {
-     return "<li>"+JSON.stringify(row)+"</li>";
-   } else {
-     return "</ul><h4>the tail</h4>"
-   }
- }
- }}}
- == Other Fun Things ==
- === Stopping iteration in a `_list` ===
- If you want to terminate iteration of a `_list` early you can return a `{stop: true}` JSON
object from any of the calls to the function that include a row object.
- 
- === Sending a Redirect ===
- In the call to `_show` or when `_list` is called with a head object you can control the
headers and status code sent to the client. An example of this would be to send a redirect
notification.
- 
- {{{#!highlight javascript
- function(doc) {
-   return {"code": 302, "body": "See other", "headers": {"Location": "/"}};
- }
- }}}
- For CouchDB version 0.9:
- 
- {{{#!highlight javascript
- function(head, row, req, row_info) {
-   if (head) {
-     return {"code": 302, "body": "See other", "headers": {"Location": "/"}};
-   } else if (row) {
-     return {stop: true};
-   } else {
-     return "."
-   }
- }
- }}}
- For CouchDB version 0.10:
- 
- {{{#!highlight javascript
- function(head, req) {
-   start({"code": 302, "headers": {"Location": "/"}});
- }
- }}}
- See [[Advanced_Shows_and_Lists_Throwing_Redirects]]
- 
- === Specifying Content-Type Response Header ===
- There are two ways to deal with a content-type header in the response to a show or list
request. The first way is to specify the content type as a member of the _show function's
response object:
- 
- {{{#!highlight javascript
- return {
-    "headers" : {"Content-Type" : "application/xml"},
-    "body" : new XML('<xml><node foo="bar"/></xml>')
- }
- }}}
- === Responding to different Content-Type Request Headers ===
- The second way to deal with content-type headers is to rely on some global helper methods
defined by CouchDB's ''<couchdb_install>/share/couchdb/server/main.js'' file. The ''registerType''
method lets you register a type key with one or more content-type strings. Please refer to
the ''main.js'' file to see content-types registered by default.
- 
- {{{#!highlight javascript
- registerType("foo", "application/foo", "application/x-foo");
- }}}
- The other global helper method for handling varying Content-Type headers is ''respondWith''.
This helper method allows you to specify different response objects depending on the type
key that corresponds to the content-type request header. The first argument is the request
object, and the second argument is a key-value object that maps type keys to functions. Each
function is expected to return an HTTP response object customized for the requested Content-Type.
- 
- {{{#!highlight javascript
- //... in your show function...
- return respondWith(req, {
-          html : function() {
-            return {
-              body:"Ha ha, you said \"" + doc.word + "\"."
-            };
-          },
-          foo : function() {
-            return {
-              body: "foofoo"
-            };
-          },
-          fallback : "html"
-        });
- }}}
- Since CouchDB 0.10.0 there is no responseWith-Method anymore. Please use the provides Method
instead. For CouchDB version 0.10:
- 
- {{{#!highlight javascript
- //... in your show function...
- provides("html", function() {return "<b>doc.title</b>";});
- provides("xml", function() {return "<text class="title">doc.title</text>";});
- }}}
- Hopefully this is enough to get started. For a more complete set of examples, see the CouchDB
test suite, especially show_documents.js and list_views.js
- 
- === ETags ===
- The ETag for your _show will always be the ETag of the underlying document. This means that
if you sneakily try to provide dynamic content by doing things in your _show function, a browser
will not refresh the page if the dynamic content changes; a browser will pass an If-None-Match
header with the ETag from the previous time it called your _show, and CouchDB will return
the same ETag (because the underlying document has not changed) ''even if the dynamic content
you added has changed'', and a 304 Not Modified header.
- 
- You can circumvent this. In CouchDB up to version 1.2, The things that go into calculating
the ETag for a _show or _list URL are: the ETag of the underlying document, the requesting
user-agent's Accept header, and the currently logged-in user's roles. So, if the thing you
want to alter in the dynamic content is a "user is logged in"/"user is not logged in" header,
make sure that your users have roles (it doesn't matter what they are); this will ensure that
a logged-in user and a non-logged-in user will get different ETags for the same _show function
on the same document.
- 
- In CouchDB 1.3, the Etag also uses the currently logged-in user's name; so different users
(and logged-in user vs non-logged-in user) will get different ETags.
- 
- === Shows without a document ===
- Technically, you do not have to pass a docid at all. You can just
- 
- {{{
- GET /db/_design/examples/_show/haha
- }}}
- to run the "haha" _show without any document at all. This can be a nice way of getting some
server-side processing done; your "haha" show function might return the contents of a template,
for example, and alter the content based on the current userCtx. Be sure and read the point
above about ETags, though.
- 

Mime
View raw message