Voici la référence de l'API HTTP de CouchDB en matière de Documents.
Un document est tout simplement un objet JSON.
Voici un exemple :
{
"_id": "j-aime-le-chocolat",
"_rev": "1-1915017252",
"Subject": "J'aime le chocolat",
"Author": "Arthur",
"PostedDate": "16/09/2009",
"Tags": ["chocolat", "gâteau", "cuisine"],
"Body": "Je me suis rendu compte aujourd'hui que j'aimais le chocolat, et surtout les gâteaux au chocolat."
}
Il n'y a pas de limitations : tant que l'objet JSON est valide, cela peut être un document.
Un autre exemple plus complexe :
{
"_id": "facture-2009-0658",
"_rev": "1-3344523300",
"Type": "Facture",
"Numero": "2009-0658",
"Date": "16/09/2009",
"Validee": true,
"Client": {
"Nom": "SARL & Co",
"Adresse": "1 rue de la Poste, 75001 Paris",
"Telephone": "01 02 03 04 05"
},
"Lignes": [
{ "Designation": "Super Machine", "PrixUnitaire": "123.76", "Quantité": 1, "MontantHT": "123.76" },
{ "Designation": "Pièce 654", "PrixUnitaire": "10.00", "Quantité": 3, "MontantHT": "30.00" }
],
"TotalHT": "153.76",
"Commentaire": "La facture est HT car mon comptable est en prison..."
}
CouchDB se réserve quelques champs spéciaux. Ils commencent par “_” (le tiret de bas, l'underscore).
C'est l'identifiant unique du document. Deux documents ayant le même ID au sein de la même base de données sont considérés comme étant les mêmes.
Le champs “_id” peuvent être :
Le champs “_id” accepte en valeur une chaîne de caractère quelconque. Toutefois, il est recommandé de n'utiliser que [a-zA-Z0-9_-] c'est à dire les caractères non accentués de a à z, de A à Z, de 0 à 9, _, - et / car l'utilisation d'autres caractères Unicode n'est ni documenté, ni testé.
C'est l'identifiant de la révision du document. Quand on travaille sur un document, il faut savoir sur quelle révision on travaille pour y appliquer les changements et régler les éventuels conflits (le “on” désignant vous-même et CouchDB) ; c'est le rôle de ce champs.
Le champs “_rev” est défini automatiquement par CouchDB.
Il y a des champs utilisés qu'occasionnellement :
Sinon, il n'y a pas d'autres champs spéciaux, mais il pourra y en avoir. Donc il est recommandé de ne pas préfixer ses noms de champs par “_” afin de ne pas créer de futurs conflits.
Chaque document a une URL, utilisée pour les actions directes, de la forme :
http://votre_serveur:5984/votre-base-de-donnee/votre-id-de-document
Quand le caractère / est présent dans l'id du document, il doit être encodé en %2F pour être utilisé dans une URL. Dans le cas des documents définissant les vues (“_design/nom-du-design”), le slash peut être utilisé tel quel juste après “_design” mais doit être encodé s'il est aussi présent après.
anniversaires-16/09/2009 => http://votre_serveur:5984/votre-base-de-donnee/anniversaires-16%2F09%2F2009 _design/nom-du-design => http://votre_serveur:5984/votre-base-de-donnee/_design/nom-du-design _design/essai-du-16/09/2009 => http://votre_serveur:5984/votre-base-de-donnee/_design/essai-du-16%2F09%2F2009
Pour récupérer le contenu d'un document, faites une requête GET sur l'URL du document :
GET /base-de-donnee/248e317fc1ea4928342b596de5449e0b HTTP/1.0 Host: 127.0.0.1:5984 Accept: application/json
La réponse du serveur :
HTTP/1.1 200 OK
Server: CouchDB/0.9.0 (Erlang OTP/R12B)
Etag: "4-4275583169"
Date: Thu, 17 Sep 2009 09:13:18 GMT
Content-Type: application/json
Content-Length: 98
Cache-Control: must-revalidate
{"_id":"248e317fc1ea4928342b596de5449e0b","_rev":"4-4275583169","Type":"Client","Nom":"SARL & Co"}
On notera que dans les headers retournés, le champs Etag contient la révision actuelle du document (attention, ne figure pas forcément dans les headers des requêtes GET avec paramètres).
Des paramètres peuvent être passés après l'URL utilisée par la requête GET :
http://votre_serveur:5984/votre-base-de-donnee/votre-id-de-document?parametre_1=valeur_1¶metre_2=valeur_2
Si la révision est disponible, rev=identifiant_de_revision retourne le document tel qu'il était à ce moment.
Si le statut de la révision demandée est missing le retour sera (pour par exemple la révision “2-1971751410”) :
HTTP/1.1 500 Internal Server Error
Server: CouchDB/0.9.0 (Erlang OTP/R12B)
Date: Thu, 17 Sep 2009 11:50:15 GMT
Content-Type: application/json
Content-Length: 66
Cache-Control: must-revalidate
{"error":"{not_found,missing}","reason":"{2,<<\"1971751410\">>}"}
revs=true donne la liste des révisions du document dans un champs ajouté “_revisions”. Exemple de retour :
{
"_id": "248e317fc1ea4928342b596de5449e0b",
"_rev": "4-4275583169",
"type": "Client",
"Nom": "SARL & Co",
"_revisions": {
"start": 4,
"ids": ["4275583169", "3094848030", "1971751410", "3934541355"]
}
}
Les révisions affichées ne sont pas forcément disponibles : la base peut avoir été compactée (retirant alors les anciennes révisions), la révision peut n'être disponible que sur un autre serveur dans le cas de réplication… Voir la page sur les révision.
revs_info=true donne la liste des révisions du document ainsi que leur statut dans un champs ajouté “_revs_info”. Exemple de retour :
{
"_id": "248e317fc1ea4928342b596de5449e0b",
"_rev": "4-4275583169",
"Type": "Client",
"Nom": "SARL & Co",
"_revs_info": [
{"rev":"4-4275583169", "status":"available"},
{"rev":"3-3094848030", "status":"missing"},
{"rev":"2-1971751410", "status":"missing"},
{"rev":"1-3934541355", "status":"deleted"}
]
}
On peut aussi faire une requête HEAD, de manière similaire à GET, pour n'obtenir que les headers renvoyés par GET (ce qui peut être utile) sans le document lui-même.
Pour créer des documents vous pouvez utiliser des requêtes PUT ou POST. Pour modifier un document, seule la requête PUT est utilisable.
Une requête POST permet de créer un document en laissant CouchDB s'occuper de l'ID.
Il est recommandé dès que possible d'éviter l'utilisation de POST car les proxy et autres intermédiaires réseaux renvoient occasionnellement ces requêtes ce qui peut entraîner la création de doublons non désirés. Aussi, le processus de création d'ID est plutôt coûteux pour CouchDB, il vaut mieux déterminer ces ID côté client (quitte à en demander un certain nombre d'un coup à CouchDB) et d'utiliser une requête PUT.
On utilise l'URL de la base de donnée et on passe le document JSON en données.
Exemple de requête :
POST /test/ HTTP/1.1
Host: 127.0.0.1:5985
Accept: application/json
Content-Length: 48
Content-Type: application/json; charset=UTF-8
{"Type":"Client","Nom":"SARL Chauffage au Bois"}
HTTP/1.1 201 Created
Server: CouchDB/0.9.0 (Erlang OTP/R12B)
Location: http://127.0.0.1:5985/test/6dafefb3c0adb84e78a73711440d44fc
Date: Thu, 17 Sep 2009 12:22:22 GMT
Content-Type: application/json
Content-Length: 73
Cache-Control: must-revalidate
{"ok":true,"id":"6dafefb3c0adb84e78a73711440d44fc","rev":"1-2474629244"}
Le serveur renvoie le code HTTP 201 Created ainsi que l'ID et la révision du document créé.
Une requête PUT permet de créer un document en spécifiant explicitement l'ID à utiliser. Ce cas est juste un cas particulier d'utilisation de PUT dans laquelle la révision n'est pas spécifié (puisque le document est nouveau).
On utilise l'URL du document, c'est à dire contenant l'ID que vous donnez.
Exemple de requête (nous souhaitons que l'ID soit “sarl-chauffage-au-bois”) :
PUT /test/sarl-chauffage-au-bois HTTP/1.1
Host: 127.0.0.1:5985
Accept: application/json
Content-Length: 48
Content-Type: application/json; charset=UTF-8
{"Type":"Client","Nom":"SARL Chauffage au Bois"}
HTTP/1.1 201 Created
Server: CouchDB/0.9.0 (Erlang OTP/R12B)
Etag: "1-3121202954"
Date: Thu, 17 Sep 2009 12:42:57 GMT
Content-Type: application/json
Content-Length: 63
Cache-Control: must-revalidate
{"ok":true,"id":"sarl-chauffage-au-bois","rev":"1-3121202954"}
Le serveur renvoie le code HTTP 201 Created ainsi que l'ID et la révision du document créé.
Une requête PUT permet de modifier un document existant. On doit spécifier l'ID du document en question et la révision du document que l'on souhaite modifier.
On utilise l'URL du document, c'est à dire contenant l'ID du document. CouchDB obtient l'ID ainsi.
Pour la révision, on l'insère dans le document sous le champs “_rev”. Y placer un champs “_id” avec l'ID n'est pas obligatoire.
Exemple de requête (nous modifions le document ayant l'ID “sarl-chauffage-au-bois” et la révision “1-3121202954”) :
PUT /test/sarl-chauffage-au-bois HTTP/1.1
Host: 127.0.0.1:5985
Accept: application/json
Content-Length: 115
Content-Type: application/json; charset=UTF-8
{"_id":"sarl-chauffage-au-bois","_rev":"1-3121202954","Type":"Client","Nom":"SARL Chauffage au Bois & Frères"}
HTTP/1.1 201 Created
Server: CouchDB/0.9.0 (Erlang OTP/R12B)
Etag: "2-1198331443"
Date: Thu, 17 Sep 2009 12:56:12 GMT
Content-Type: application/json
Content-Length: 63
Cache-Control: must-revalidate
{"ok":true,"id":"sarl-chauffage-au-bois","rev":"2-1198331443"}
Le serveur renvoie le code HTTP 201 Created ainsi que l'ID et la nouvelle révision du document.
Si la révision du document ne correspond pas à la révision de la version actuelle du document sur le serveur, le serveur répondra :
HTTP/1.1 409 Conflict
Server: CouchDB/0.9.0 (Erlang OTP/R12B)
Date: Thu, 17 Sep 2009 13:03:43 GMT
Content-Type: application/json
Content-Length: 58
Cache-Control: must-revalidate
{"error":"conflict","reason":"Document update conflict."}
Les cas de conflits lors de la modification des documents sont abordés sur la page conflits.
Les paramètres sont passés après l'URL du document, de la même manière que pour GET :
http://votre_serveur:5984/votre-base-de-donnee/votre-id-de-document?parametre_1=valeur_1¶metre_2=valeur_2
Le paramètre batch=ok permet d'atteindre un débit d'écriture plus élevé au prix d'une garantie de succès inférieure. Quand un PUT (marche aussi avec POST) est envoyé en utilisant cette option, le document n'est pas immédiatement écrit sur le disque. Au contraire, il est stockée en mémoire (par utilisateur) pour une seconde ou deux (ou jusqu'à que le nombre de documents en mémoire atteint un certain point). Dès que le seuil est atteint, les documents se sont écrits sur le disque. Au lieu d'attendre que le document soit écrit sur le disque pour répondre, CouchDB renvoie le code HTTP 202 Accepted immédiatement.
Le paramètre batch=ok n'est pas adapté pour des données cruciales, mais il est idéal pour des applications de logging, par exemple, qui peuvent accepter le risque qu'une faible proportion de modifications soit perdue lors d'un crash. L'écriture des documents en mémoire sur le disque peut également être faite manuellement en utilisant l'API _ensure_full_commit.
Pour supprimer un document, faites une requête DELETE sur l'URL du document, en y ajoutant le paramètre “rev” contenant la révision actuelle du document.
DELETE /test/6dafefb3c0adb84e78a73711440d44fc?rev=1-2474629244 HTTP/1.1 Host: 127.0.0.1:5985 Accept: application/json
HTTP/1.1 200 OK
Server: CouchDB/0.9.0 (Erlang OTP/R12B)
Etag: "2-4290809874"
Date: Thu, 17 Sep 2009 14:18:00 GMT
Content-Type: application/json
Content-Length: 73
Cache-Control: must-revalidate
{"ok":true,"id":"6dafefb3c0adb84e78a73711440d44fc","rev":"2-4290809874"}
Le serveur retourne un nouveau numéro de révision correspondant à la suppression.
Vous pouvez aussi procéder en passant la révision via le header Etag “If-Match” :
DELETE /test/6dafefb3c0adb84e78a73711440d44fc HTTP/1.1 Host: 127.0.0.1:5985 Accept: application/json If-Match: "1-2474629244"
Si vous ne spécifiez pas la révision du document en paramètre de la requête (ou si vous spécifiez un qui n'est pas la révision actuelle du document), le serveur vous renverra le code HTTP 409 Conflict avec comme contenu :
{"error":"conflict","reason":"Document update conflict."}
Si vous essayer de supprimer un document déjà supprimé, le serveur vous renverra le code HTTP 404 Object Not Found avec comme contenu :
{"error":"not_found","reason":"deleted"}
Pour copier un document, faites une requête COPY sur l'URL du document source. Vous devez spécifier l'ID du document cible à créer via le header “Destination”.
La requête COPY est une extension non standard de HTTP. Cela permet de dupliquer les documents sans échanger leur contenu avec CouchDB.
Il n'est pas possible de copier des documents entre différentes base de données.
Exemple :
COPY /votre-base-de-donnee/votre-id-de-document HTTP/1.1 Destination: votre-id-de-document-nouveau
HTTP/1.1 201 Created
Server: CouchDB/0.9.0 (Erlang OTP/R12B)
Etag: "1-7865379365"
Date: Thu, 17 Sep 2009 14:18:00 GMT
Content-Type: application/json
Content-Length: 68
Cache-Control: must-revalidate
{"ok":true,"id":"votre-id-de-document-nouveau","rev":"1-7865379365"}
Si vous souhaitez remplacer un document existant, vous devez spécifier la révision actuelle du document cible avec un paramètre “rev” dans le header “Destination” :
COPY /votre-base-de-donnee/votre-id-de-document HTTP/1.1 Destination: votre-id-de-document-nouveau?rev=id-de-revision
La réponse du serveur est la même.
Pendant une période de 6 mois, entre les versions 0.8 et 0.9, la version de développement de CouchDB a inclus la méthode MOVE, non standard. Comme MOVE n'est que COPY suivit de DELETE et que CouchDB ne peut pas garantir une atomicité raisonnable entre les requêtes COPY et MOVE sur un seul ou sur plusieurs noeuds, cela a été retiré avant la sortie de la version 0.9 de CouchDB.