couchdb-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Simeon F. Willbanks" <sim...@simeons.net>
Subject validate_doc_update responsibilities
Date Wed, 09 Mar 2011 21:10:44 GMT
>From the 'CouchDB The Definitive Guide', "CouchDB uses the
validate_doc_update function to prevent invalid or unauthorized
document updates from proceeding." This clearly defines the
validate_doc_update function's responsibility. That said, can we
extend this responsibility a bit? I'd rather not redefine valid
document attributes in my external application since
validate_doc_update is already doing the work (DRY). Maybe the
application can query the validate_doc_update function for the exact
attributes of a valid document. Here is a proof of concept
validate_doc_update function.

function(newDoc, oldDoc, userCtx) {
  Errors = {count: 0};

  function Message(field, type, text) {
    this.type = type || 'string';
    this.text = text || field + ' is required';
    this.required = true;
  };

  function require(field, type, text) {
    if (!newDoc[field]) {
      Errors[field] = new Message(field, type, text);
      Errors.count += 1;
    };
  };

  if (newDoc.type == 'post') {
    require('title');
    require('created_at', 'datetime');
    require('body');
    require('author');
  };

  if (newDoc.type == 'comment') {
    require('name');
    require('created_at', 'datetime');
    require('comment', 'string', 'You may not leave an empty comment');
  };

  if (Errors.count > 0) {
    throw({forbidden: JSON.stringify(Errors)});
  };
}

In my application, before putting a new document or building a
document input UI (web form), I can "query" the validate_doc_update
function like so:

$ curl -X PUT couchdb:5984/basic/a1a0d5f1e202b48e5bc55f616d0021ff -d
'{"type":"post"}'
{"error":"forbidden","reason":"{\"count\":4,\"title\":{\"type\":\"string\",\"text\":\"title
is required\",\"required\":true},\"created_at\":{\"type\":\"datetime\",\"text\":\"created_at
is required\",\"required\":true},\"body\":{\"type\":\"string\",\"text\":\"body
is required\",\"required\":true},\"author\":{\"type\":\"string\",\"text\":\"author
is required\",\"required\":true}}"}

>From the response, I can decode the JSON object's reason property to a
useful array.

array
  'count' => int 4
  'title' =>
    array
      'type' => string 'string' (length=6)
      'text' => string 'title is required' (length=17)
      'required' => boolean true
  'created_at' =>
    array
      'type' => string 'datetime' (length=8)
      'text' => string 'created_at is required' (length=22)
      'required' => boolean true
  'body' =>
    array
      'type' => string 'string' (length=6)
      'text' => string 'body is required' (length=16)
      'required' => boolean true
  'author' =>
    array
      'type' => string 'string' (length=6)
      'text' => string 'author is required' (length=18)
      'required' => boolean true

>From this array, I can build the input UI or validate the new document
before putting.

To reiterate, I am trying to DRY up the validation
rules/responsibilities by defining them in one spot. This proof of
concept uses the validate_doc_update function in CouchDB. The
validate_doc_update function is now responsible for preventing invalid
documents from being PUT to CouchDB, and it can respond to application
queries for what constitutes a valid document.

So, is this a bad idea? Is there a more idiomatic way to accomplish this goal?

Thanks,
Simeon

Mime
View raw message