Bei Holisticon arbeiten wir gerade an einer kleinen (browserbasierten) App, die unsere Bibliotheksverwaltung erleichtern soll. Wir möchten also z.B. neue Bücher mit der Kamera eines Smartphones scannen, von Google Books identifizieren und mit Informationen anreichern lassen und dann einen Datensatz speichern. Und weil verschiedene Smartphones natürlich denselben Datenbestand nutzen sollen, brauchen wir eine Datenbank. Der eine oder andere hat es sich bereits gedacht: Wir haben uns für CouchDB entschieden.
Motivation – Warum CouchDB?
Zuerst einmal soll sich der Entwicklungsaufwand für uns in Grenzen halten. Wir möchten also keine Schemata für ein RDBMS entwerfen. Unsere Philosophie an dieser Stelle: Daten rein und gut.
Daten, was für Daten? Alles fängt mit dem Scannen der Identifikationsnummer eines Buches an. Mit der ISBN schlagen wir bei Google Books das Buch nach und erhalten ein JSON-Dokument. Natürlich war hier der Groschen gefallen – „JSON“ und „Dokument“. Wir brauchen also ein Document Store, das JSON versteht. Und weil wir außerdem keinen Server Marke Eigenbau hinter die App stellen wollten, haben wir RESTful als weiteres Kriterium aufgenommen und festgelegt, dass der Umgang mit Konflikten etc. in der App selbst implementiert werden muss. Tja, welche Datenbank vereinigt all unsere Anforderungen?
Installation
Wir arbeiten auf unseren Servern teilweise noch mit Ubuntu 12.04. Ja, das ist schon etwas eingestaubt (bitte nicht angreifen) und von Haus aus gibt es keine Pakete für eine aktuelle CouchDB. Nach etwas Recherche haben wir aber ein Personal Package Archive (PPA) gefunden, das CouchDB 1.5 bereitstellt: „ppa:cli/couchdb“ – das ist aktuell genug.
Und so sieht das Installations-Script aus (gut, wir haben das von Hand gemacht):
apt-get install python-software-properties # Damit add-apt-repository aufgerufen warden kann add-apt-repository ppa:cli/couchdb # Das PPA hinzufügen apt-get update # Die Paketliste aktualisieren apt-get install couchdb # ???
Wow, das ging schnell!
Konfiguration
Wir wollten nur sichere Verbindungen und authentifizierte Benutzer zulassen. Kein Problem, das ist schnell eingerichtet. Auch brauchen wir Cross-origin resource sharing (CORS), damit unsere Datenbank aus einer browserbasierten App heraus aufgerufen werden kann. (*flüstert* Und für andere Sachen wird das sicher auch praktisch sein.)
Hier ist eine Übersicht über die geänderten Einstellungen der local.ini:
[httpd] bind_address = 0.0.0.0 enable_cors = true [daemons] httpsd = {couch_httpd, start_link, [https]} [ssl] cert_file = /path/to/my.crt.pem key_file = /path/to/my.key.pem password = Password, if required [cors] origins = * methods = GET,POST,PUT,DELETE headers = Authorization,Content-Type,Accept
Bei CORS ist aber Vorsicht geboten! CouchDB 1.5 ist leider nicht Spec-konform.
<Exkurs ueber=“CORS“>
Bei CORS wird – ganz grob – vor der eigentlichen Anfrage ein Preflight (OPTIONS) an den Server gestellt, damit der Client sich informieren kann, ob die anstehende Anfrage unterstützt wird und, wenn ja, in welcher Form. Anhand der Antwort kann der Client ermitteln, ob er die eigentliche Anfrage überhaupt noch stellen möchte.
Ein Client könnte z.B. die Headers
Access-Control-Request-Method: POST Access-Control-Request-Headers: authorization,content-type
an CouchDB schicken und die Antwort
Access-Control-Allow-Methods: GET, POST, PUT, DELETE Access-Control-Allow-Headers: authorization,content-type
erhalten.
Wäre in der Menge der headers in der [CORS]-Sektion z.B. Content-Type nicht enthalten, würde CouchDB – fälschlicherweise – 401 Unauthorized senden. Richtig wäre die Schnittmenge aus Access-Control-Request-Headers und headers der [CORS]-Sektion in Access-Control-Allow-Headers zu antworten. 401 Unauthorized ist niemals richtig als Antwort auf OPTIONS im Rahmen von CORS. Die Erklärung dafür liegt in der Spec: 401 Unauthorized bedeutet, dass für die Anfrage eine Benutzer-Autorisierung vorliegen muss. Eine OPTIONS-Anfrage wird von Spec-konformen Browsern immer ohne Autorisierung gestellt (7.1.5 „Exclude user credentials“).
</Exkurs>
Und zum krönenden Abschluss haben wir noch den Port 6984 (der CouchDB-Standard-SSL-Port) auf allen relevanten Schnittstellen geöffnet, damit die Arbeit beginnen kann.
Fazit
Es ist wie immer: Wenn man weiß, worauf es ankommt und wo man welche Stellschraube findet, ist alles kein Problem. CouchDB ist schnell verstanden und wirklich einfach zu verwenden. Jetzt heißt es „Scan On“ und mal gucken, wann wir anfangen müssen zu clustern.