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 >> >>> >> >> >> > >> >
