Janez,

Actually, my CouchDB instance is connecting to multiple interfaces of
an application. Those interfaces include PHP and Python scripts. Both
languages are making GET, PUT and DELETE requests to a CouchDB
database. From my example, the database name is 'basic.'  Since I have
multiple languages and machines in play, I am trying to centralize my
model validations. The validate_doc_update function seemed like a
decent candidate for this location since all operations flow through
it. Does this make sense?

Thanks,
Simeon

On Thu, Mar 10, 2011 at 1:21 AM, Janez Štupar <[email protected]> wrote:
> 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 
> <[email protected]>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 <[email protected]> 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 <[email protected]>
>> 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 <[email protected]>
>> 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
>> >>>
>> >>
>> >
>>
>

Reply via email to