couchdb-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Janez Štupar <janez.stu...@gmail.com>
Subject Re: validate_doc_update responsibilities
Date Thu, 10 Mar 2011 09:21:06 GMT
Whoah Caolan and Simeon,

have you looked into the couchapp.js framework that Chris Anderson has
built?

It pulls the design document to browser and enables you to run specific code
from it. Id propose that you look into extending and/or clearing up
couchapp.

I understand that we might have different scenarios here.

@Caolan: like i said, Couchapp already does that. IMHO it would need some
clearing up so it doesn't pull exactly the whole design document to client
(with base64 images and CSS + other attachments) - I hope to do it someday
if  I come around to it.

@Simeon:What Justin proposed would work in browser, not in middleware. So I
guess youre using node.js? If so I'd look into improving couchapp.js to work
on node - then you pull the design doc from couchdb and use same relative
addresing design document wise.

Kind regards, -Janez

On Thu, Mar 10, 2011 at 9:47 AM, Caolan McMahon <caolan.mcmahon@gmail.com>wrote:

> Simeon,
>
> If you're interested in the concept of sharing code, you might want to
> take a look at Kanso (http://kansojs.org), which aims to bring all the
> features of the design doc to the client-side. This means you can call
> validate_doc_update on a document from the browser, or even call list,
> show and update functions too. Still early days though :)
>
> Caolan
>
>
> On 10 March 2011 00:00, Simeon F. Willbanks <simeon@simeons.net> wrote:
> > Justin,
> >
> > Thank you for the reply and helping me brainstorm a solution. I like
> > the !code macro idea, but my CouchDB server isn't on the same machine
> > as my application. They communicate through a network. Could I do
> > this?
> >
> > function(newDoc, oldDoc, userCtx) {
> >  //!code path/to/validate.py
> >  validate(newDoc, oldDoc, userCtx);
> > }
> >
> > path/to/validate.py would be network aware and would return valid
> JavaScript.
> >
> > Thanks,
> > Simeon
> >
> > On Wed, Mar 9, 2011 at 1:27 PM, Justin Walgran <jwalgran@azavea.com>
> wrote:
> >> Simeon,
> >>
> >> the !code macro in CouchApp was created so you can DRY up your
> >> functions in the exact way you want. If you extract your validator,
> >> you can include it in both your validate_doc_update function and your
> >> client code. Something like this:
> >>
> >> function(newDoc, oldDoc, userCtx) {
> >>  //!code path/to/validate.js
> >>  validate(newDoc, oldDoc, userCtx);
> >> }
> >>
> >> // Content of validate.js
> >> var validate = function(newDoc, oldDoc, userCtx) {
> >>        var Errors = {count: 0};
> >>
> >>        var Message = function(field, type, text) {
> >>                this.type = type || 'string';
> >>                this.text = text || field + ' is required';
> >>                this.required = true;
> >>        };
> >>
> >>        var require = function(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)});
> >>        };
> >> }
> >>
> >> If you refactor a little further, you could go the next step and
> >> generate a form from the configuration of the validator without the
> >> making the extra, intentionally bad request to the server.
> >>
> >> Justin
> >>
> >>
> >> On Wed, Mar 9, 2011 at 4:10 PM, Simeon F. Willbanks <simeon@simeons.net>
> wrote:
> >>> 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
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message