Une introduction à l'api Document HTTP.

Nommage/Addressage

Les documents stockés dans CouchDB ont une DocID. Les DocIDs sont des identifiants uniques sous formes de chaines de caractères sensibles à la casse qui identifient un document. Deux documents ne peuvent avoir le même identifiant dans une même base de données.

http://localhost:5984/test/some_doc_id
http://localhost:5984/test/another_doc_id
http://localhost:5984/test/BA1F48C5418E4E68E5183D5BD1F06476

Les URL ci_dessus pointent vers some_doc_id, another_doc_id and BA1F48C5418E4E68E5183D5B!D1F06476 dans la base test.

Id Document valide

JSON

Un document CouchDB est un simple objet JSON. (Accompagnées des informations de révision si ?full=true dans les arguments de l'URL.

Voici un exemple de document :

{
 "_id":"discussion_tables",
 "_rev":"D1C946B7",
 "Subject":"I like Planktion",
 "Author":"Rusty",
 "PostedDate":"2006-08-15T17:30:12-04:00",
 "Tags":["plankton", "baseball", "decisions"],
 "Body":"I decided today that I don't like baseball. I like plankton."
}

Un document peut être n'importe quel objet JSON, mais les champs de premier niveau ayant un nom commençant par _ sont réservés à CouchDB. Les exemples évidents sont les champs _id et _rev, comme on l'a vu ci-dessus.

Autre exemmple :

{
 "_id":"discussion_tables",
 "_rev":"D1C946B7",
 "Subrise":true,
 "Sunset":false,
 "FullHours":[1,2,3,4,5,6,7,8,9,10],
 "Activities": [
   {"Name":"Football", "Duration":2, "DurationUnit":"Hours"},
   {"Name":"Breakfast", "Duration":40, "DurationUnit":"Minutes", "Attendees":["Jan", "Damien", "Laura", "Gwendolyn", "Roseanna"]}
 ]
}

Attention, par défaut la structure est à plat; dans ce cas l'attribut Activities est une structure donnée par l'utilisateur.

Tous les documents

Pour obtenir une liste de tous les documents dans la base utilisez l'URI spéciale _all_docs :

GET somedatabase/_all_docs HTTP/1.0
Date: Thu, 17 Aug 2006 05:39:28 +0000GMT

Qui retourne une liste de tous les documents avec leurs ids révisons, trié par DocId (sensible à la casse) :

HTTP/1.1 200 OK
Date: Thu, 17 Aug 2006 05:39:28 +0000GMT
Content-Type: application/json
Connection: close

{
  "total_rows": 3, "offset": 0, "rows": [
    {"id": "doc1", "key": "doc1", "value": {"_rev": "4324BB"}},
    {"id": "doc2", "key": "doc2", "value": {"_rev":"2441HF"}},
    {"id": "doc3", "key": "doc3", "value": {"_rev":"74EC24"}}
  ]
}

Utilisez l'argument descending=true pour inverser l'ordre dans cette table :

Ce qui retourne la même chose que ci-dessus mais dans l'ordre inverse :

HTTP/1.1 200 OK
Date: Thu, 17 Aug 2006 05:39:28 +0000GMT
Content-Type: application/json
Connection: close

{
  "total_rows": 3, "offset": 0, "rows": [
    {"id": "doc3", "key": "doc3", "value": {"_rev":"74EC24"}}
    {"id": "doc2", "key": "doc2", "value": {"_rev":"2441HF"}},
    {"id": "doc1", "key": "doc1", "value": {"_rev": "4324BB"}},
  ]
}

Les options startkey et count peuvent en outre être utilisées pour limiter le nombre de résultats obtenus :

GET somedatabase/_all_docs?startkey=doc2&count=2 HTTP/1.0
Date: Thu, 17 Aug 2006 05:39:28 +0000GMT

Qui retourne :

HTTP/1.1 200 OK
Date: Thu, 17 Aug 2006 05:39:28 +0000GMT
Content-Type: application/json
Connection: close

{
  "total_rows": 3, "offset": 1, "rows": [
    {"id": "doc2", "key": "doc2", "value": {"_rev":"2441HF"}},
    {"id": "doc3", "key": "doc3", "value": {"_rev":"74EC24"}}
  ]
}

Combiné avec descending :

GET somedatabase/_all_docs?startkey=doc2&count=2&descending=true HTTP/1.0
Date: Thu, 17 Aug 2006 05:39:28 +0000GMT

Retourne :

HTTP/1.1 200 OK
Date: Thu, 17 Aug 2006 05:39:28 +0000GMT
Content-Type: application/json
Connection: close

{
  "total_rows": 3, "offset": 1, "rows": [
    {"id": "doc3", "key": "doc3", "value": {"_rev":"74EC24"}}
    {"id": "doc2", "key": "doc2", "value": {"_rev":"2441HF"}},
  ]
}

Travailler sur les documents en HTTP

GET

Pour récupérer un document, envoyez simplement un GET sur l'URL du document :

GET /somedatabase/some_doc_id HTTP/1.0
Date: Thu, 17 Aug 2006 05:39:28 +0000GMT

Voici la réponse du serveur :

HTTP/1.1 200 OK
Date: Thu, 17 Aug 2006 05:39:28 +0000GMT
Content-Type: application/json
Connection: close

{
 "_id":"123BAC",
 "_rev":"946B7D1C",
 "Subject":"I like Planktion",
 "Author":"Rusty",
 "PostedDate":"2006-08-15T17:30:12Z-04:00",
 "Tags":["plankton", "baseball", "decisions"],
 "Body":"I decided today that I don't like baseball. I like plankton."
}

Accéder aux révisions précedentes

Voir RevisionsDeDocuments pour plus d'information sur les révisions.

L'exemple ci-dessus récupère la révisions en cours. Vous pouvez récupérer une révision particulière avec la syntaxe suivante :

GET /somedatabase/some_doc_id?rev=946B7D1C HTTP/1.0
Date: Thu, 17 Aug 2006 05:39:28 +0000GMT

Pour obtenir la liste des révisions disponibles d'un document, vous pouvez faire :

GET /somedatabase/some_doc_id?revs=true HTTP/1.0
Date: Thu, 17 Aug 2006 05:39:28 +0000GMT

Cela retourne la dernière révisions du document mais avec le champ _revs, la valeur devient une liste de toutes les IDs révison disponibles. Attention toutes les révisons ne sont pas forcemment encore stockées sur le disque. Par exemple, une ancienne révision a pu être supprimée lors du compactage de la base, ou peu exister seulement dans une base différente si celle-ci a été répliquée.

Pour obtenir plus d'informations sur les révisiosn d'un document disponibles, utilisez le paramètre revs_info à la place. Dans ce cas le résultat JSON contiendra une propriété revs_info qui est un tableau d'objets :

{
  "_revs_info": [
    {"rev": "123456", "status": "disk"},
    {"rev": "234567", "status": "missing"},
    {"rev": "345678", "status": "deleted"},
  ]
}

Ici disk signifie que la révision est enregistrée sur le disque et peut encore être recupérée. Les autres valeurs indiquent que le contenu de la révision n'est plus disponible.

PUT

Pour créer un nouveau document vous pouvez soit envoyer une requête POST, soit une requête PUT. Pour créer/mettre à jour un document nommé, uttilisez PUT, l'URL doit pointer ver l'emplacement du document.

L'exemple suivant est une requête HTTP PUT. CouchDB va créer une nouvelle ID révision et sauver le document avec.

PUT /somedatabase/some_doc_id HTTP/1.0
Content-Length: 245
Date: Thu, 17 Aug 2006 05:39:28 +0000GMT
Content-Type: application/json

{
  "Subject":"I like Planktion",
  "Author":"Rusty",
  "PostedDate":"2006-08-15T17:30:12-04:00",
  "Tags":["plankton", "baseball", "decisions"],
  "Body":"I decided today that I don't like baseball. I like plankton."
}

Voici la réponse du serveur.

HTTP/1.1 201 OK
Date: Thu, 17 Aug 2006 05:39:28 +0000GMT
Content-Type: application/json
Connection: close

{"ok": true, "id": "some_doc_id", "rev": "946B7D1C"}

Pour mettre à jour un document existant, vous pouvez aussi envoyer une requête PUT. Dans ce cas l'objet JSON doit contenir une propriété _rev qui permet à CouchDB de connaître sur quelle révison la modification est basée. Si la dernière révison du document qui est stockée, ne correspond pas, une erreur de conflit 409 est renvoyée.

Si le numéro de révision correspond à ce qui est dans la base, un nouveau numéro de révision est généré et renvoyé au client.

Par exemple :

PUT /somedatabase/some_doc_id HTTP/1.0
Content-Length: 245
Date: Thu, 17 Aug 2006 05:39:28 +0000GMT
Content-Type: application/json

{
  "_id":"some_doc_id",
  "_rev":"946B7D1C",
  "Subject":"I like Planktion",
  "Author":"Rusty",
  "PostedDate":"2006-08-15T17:30:12-04:00",
  "Tags":["plankton", "baseball", "decisions"],
  "Body":"I decided today that I don't like baseball. I like plankton."
}

Ici la réponse du serveur si la révision courante du document some_doc_id enregistrée dans la base est 946B7D1C.

HTTP/1.1 201 OK
Date: Thu, 17 Aug 2006 05:39:28 +0000GMT
Content-Type: application/json
Connection: close

{"ok":true, "id":"some_doc_id", "rev":"946B7D1C"}

Ici la réponse du serveur, si la mise à jour crée un conflit (si la révision courante du document some_doc_id stockée dans la base est 946B7D1C).

HTTP/1.1 409 CONFLICT
Date: Thu, 17 Aug 2006 05:39:28 +0000GMT
Content-Length: 33
Connection: close

{"error":{"id":"conflict","reason":"3073715634"}}

POST

La requête POST peut être utilisée pour créer un document dont l'ID est génerée par le serveur. Pour créer un document nommé, utilisez à la place la méthode PUT.

L'exemple suivant est une requête POST. Le serveur COUCHDB va générer un nouveau DocID et une ID révision et enregistrer le document avec.

POST /somedatabase/ HTTP/1.0
Content-Length: 245
Date: Thu, 17 Aug 2006 05:39:28 +0000GMT
Content-Type: application/json

{
  "Subject":"I like Planktion",
  "Author":"Rusty",
  "PostedDate":"2006-08-15T17:30:12-04:00",
  "Tags":["plankton", "baseball", "decisions"],
  "Body":"I decided today that I don't like baseball. I like plankton."
}

La réponse du serveur :

HTTP/1.1 201 Created
Date: Thu, 17 Aug 2006 05:39:28 +0000GMT
Content-Type: application/json
Connection: close

{"ok":true, "id":"123BAC", "rev":"946B7D1C"}

Modifiez plusieurs documents en une seule requête

CouchDB propose une fonctionnalité d'insertion/mise à jour en masse. Pour l'utilisez envoyez une requete POST à l'URI /{dbname}/_bulk_docs, avec un document JSON contenant la liste de tous les documents à insérer ou mettre à jour. Le format actuel de la requête et de la réponse diffèrent entre CouchdDB 0.7.2 et 0.8.9-incubating (ou le trunk).

CouchDB 0.7.2:

[
  {"_id": "0", "integer": 0, "string": "0"},
  {"_id": "1", "integer": 1, "string": "1"},
  {"_id": "2", "integer": 2, "string": "2"}
]

CouchDB 0.8.0-incubation (et trunk):

{
  "docs": [
    {"_id": "0", "integer": 0, "string": "0"},
    {"_id": "1", "integer": 1, "string": "1"},
    {"_id": "2", "integer": 2, "string": "2"}
  ]
}

Si vous omettez le paramètre _id, CouchdBD va génerer des IDs uniques pour vous comme il le fait pour une simple requêtePOST sur l'URI de la base.

La réponse pour une telle requête de masse:

CouchDB 0.7.2:

{
  "ok":true,
  "results": [
    {"ok": true, "id": "0", "rev": "3682408536"},
    {"ok": true, "id": "1", "rev": "3206753266"},
    {"ok": true, "id": "2", "rev": "426742535"}
  ]
}

CouchDB 0.8.0-incubating (et trunk):

{
  "ok":true,
  "new_revs": [
    {"id": "0", "rev": "3682408536"},
    {"id": "1", "rev": "3206753266"},
    {"id": "2", "rev": "426742535"}
  ]
}

La mise à jour de documents existants requière le membre _rev de la révison à mettre à jour. Pour effacer un document mettez _deleted à true. CouchDB 0.8.0-incubating (ou trunk):

{
  "docs": [
    {"_id": "0", "_rev": "3682408536", _deleted=true},
    {"_id": "1", "_rev": "3206753266", "integer": 2, "string": "2"},
    {"_id": "2", "_rev": "426742535", "integer": 3, "string": "3"}
  ]
}

Attention, CouchDB retourne une réponse avec l'id et la révision de chaque document passé dans l'insertion/mise à jour en masse, même si ceux-ci viennent d'être supprimés.

DELETE

Pour supprimer un document, envoyez une requête DELETE sur l'URL du document avec le paramètre rev de la révison courante du document. Si celle-ci réussit, l'ID de la révison correspondant à la suppression est renvoyée.

DELETE /somedatabase/some_doc?rev=1582603387 HTTP/1.0
Date: Thu, 17 Aug 2006 05:39:28 +0000GMT

Réponse:

HTTP/1.1 202 OK
Date: Thu, 17 Aug 2006 05:39:28 +0000GMT
Content-Type: application/json
Connection: close

{"ok":true,"rev":"2839830636"}

Attachements

Les documents peuvent avoir des attachements comme les emails. À la création, les attachements vont dans un attribut du document spécial _attachments. Ils correspondent à une structure JSON qui contient le nom, le content_type et la donnée codée en base64 de l'attachement. Un document peut avoir n'importe quel nombre d'attachements.

Lorsque vous récupérez les documents, seles les métadonnées de l'attachement sont incluses, pas le contenu. Il doit être téléchargé à part en utilisant une URI spéciale.

Création d'un document avec un attachement :

{
  "_id":"attachment_doc",
  "_attachments":
  {
    "foo.txt":
    {
      "content_type":"text\/plain",
      "data": "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
    }
  }
}

Attention les données base64 envoyées doivent être sur une seule ligne, donc préparez vos données en supprimant tous retours à la ligne et nouvelles lignes.

Récupérer le document :

GET /database/attachment_doc

CouchDB répond:

{
  "_id":"attachment_doc",
  "_rev":1589456116,
  "_attachments":
  {
    "foo.txt":
    {
      "stub":true,
      "content_type":"text\/plain",
      "length":29
    }
  }
}

Notez l'attribut "stub":true qqui montre que ce n'est pas un attachement complet. Notez aussi la taille de l'atttribut ajoutée automatiquement.

Récupérez l'attachement :

GET /database/attachment_doc/foo.txt

CouchDB retoune

This is a base64 encoded text

Automatiquement décodé!

Plusieurs Attachments

Créer un document avec un attachement:

{
  "_id":"attachment_doc",
  "_attachments":
  {
    "foo.txt":
    {
      "content_type":"text\/plain",
      "data": "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
    },

   "bar.txt":
    {
      "content_type":"text\/plain",
      "data": "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
    }
  }
}

ETags/Cache

CouchDB envoie un entête ETag à chaque requête de document. L'entête Etag est simplement une révison de document.

Par exemple pour une requête GET:

GET /database/123182719287

Résultat en réponse contenant les headers suivants :

cache-control: no-cache,
pragma: no-cache
expires: Tue, 13 Nov 2007 23:09:50 GMT
transfer-encoding: chunked
content-type: text/plain;charset=utf-8
etag: "615790463"

les requêtes POST retournent aussi un entête ETag pour les nouveaux documents crées ou les mises à jour de documents.

ApiDocumentHttp (last edited 2010-01-11 14:11:27 by BrunoRohée)