Changeset 481 for Dev


Ignore:
Timestamp:
11/30/13 22:45:04 (11 years ago)
Author:
hendrikvanantwerpen
Message:

Hide database details behind decent API. Client needs to start using it now.

Location:
Dev/trunk/src/server
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • Dev/trunk/src/server/app.js

    r478 r481  
    88  , CouchDB = require('./util/couch').CouchDB
    99  , _ = require("underscore")
     10  , tv4 = require("tv4")
    1011  ;
    1112
     
    2425    var couch = new CouchDB(settings.couchDbURL);
    2526   
     27    var schema = require("./config/couchdb-schema.json");
     28    return couch.get("schemaInfo").then(function(schemaInfo){
     29        if (schemaInfo.version !== schema.version) {
     30            var msg =  "Database has version "+schemaInfo.version+" but we expect version "+schema.version;
     31            throw new Error(msg);
     32        }
     33        return configureApp(settings,couch,schema);
     34    });
     35
     36};
     37
     38function configureApp(settings,couch,schema) {
     39
    2640    function clientPath(relativePath) {
    2741        return path.resolve(__dirname+'/../client/'+relativePath);
     
    7791    });
    7892
    79     // data is proxied to couch
    80     app.use('/data', ensureAuthenticated);
    81     app.use('/data', proxy(settings.couchDbURL));
    82 
    8393    // post to this url to login
    8494    app.post(
     
    102112        });
    103113
    104     app.get(
    105         '/api/surveyRuns/:id',
    106         function(req,res){
     114    function makeDocsGet(type) {
     115        return function(req,res) {
     116            var url = '_design/default/_view/by_type?key='+JSON.stringify(type);
     117            couch.get(url).then(function(result){
     118                var items = _.map(result.rows, function(item) { return item.value; });
     119                res.send(200, items);
     120            }, function(error){
     121                res.send(404, {error: "Cannot find collection"});
     122            });
     123        };
     124    }
     125    function makeDocGet_id(type) {
     126        return function(req,res) {
    107127            var id = req.params.id;
    108128            couch.get(id).then(function(result){
    109                 if ( result.type === 'SurveyRun') {
     129                if ( result.type === type ) {
    110130                    res.send(200, result);
    111131                } else {
    112                     res.send(404, {error: "Cannot find survey run "+id});
     132                    res.send(404, {error: "Document "+id+" is not a "+type});
    113133                }
    114134            }, function(error){
    115135                res.send(404, {error: "Cannot find survey run "+id});
    116136            });
    117         });
    118     app.get(
    119         '/api/responses/:id',
    120         function(req,res){
    121             var id = req.params.id;
    122             couch.get(id).then(function(result){
    123                 if ( result.type === 'Response') {
     137        };
     138    }
     139    function makeDocPut_id(type) {
     140        return function(req,res) {
     141            var id = req.params.id;
     142            var doc = req.body;
     143            if ( doc.type === type && tv4.validateResult(doc, schema) ) {
     144                couch.put(id,doc).then(function(result){
    124145                    res.send(200, result);
    125                 } else {
    126                     res.send(404, {error: "Cannot find response "+id});
    127                 }
    128             }, function(error){
    129                 res.send(404, {error: "Cannot find response "+id});
    130             });
    131         });
    132     app.post(
    133         '/api/responses',
    134         function(req,res){
    135             console.log(req.body);
    136             couch.post(req.body).then(function(result){
    137                 res.send(200, result);
    138             }, function(error){
    139                 res.send(500, error);
    140             });
    141         });
    142     app.put(
    143         '/api/responses/:id',
    144         function(req,res){
    145             var id = req.params.id;
    146             couch.put(id,req.body).then(function(result){
    147                 res.send(200, result);
    148             }, function(error){
    149                 res.send(500, error);
    150             });
    151         });
    152     app.delete(
    153         '/api/responses/:id',
    154         function(req,res){
     146                }, function(error){
     147                    res.send(500, error);
     148                });
     149            } else {
     150                res.send(400,{error: "Document failed schema verification."});
     151            }
     152        };
     153    }
     154    function makeDocDel_id(type) {
     155        return function(req,res) {
    155156            var id = req.params.id;
    156157            var rev = req.query.rev;
     
    160161                res.send(500, error);
    161162            });
    162         });
    163    
    164     // generate CSV download of responses
    165     app.get(
    166         '/api/surveyRuns/:id/responses.csv',
     163        };
     164    }
     165    function makeDocPost(type) {
     166        return function(req,res) {
     167            var doc = req.body;
     168            if ( doc.type === type && tv4.validateResult(doc, schema) ) {
     169                couch.post(req.body).then(function(result){
     170                    res.send(200, result);
     171                }, function(error){
     172                    res.send(500, error);
     173                });
     174            } else {
     175                res.send(400,{error: "Document failed schema verification."});
     176            }
     177        };
     178    }
     179    function notImplemented(req,res) {
     180        res.send(501,{error:"API not implemented yet."});
     181    }
     182
     183    // Questions
     184    app.get('/api/questions',
     185        ensureAuthenticated,
     186        makeDocsGet('Question'));
     187    app.get('/api/questions/:id',
     188        ensureAuthenticated,
     189        makeDocGet_id('Question'));
     190    app.post('/api/questions',
     191        ensureAuthenticated,
     192        makeDocPost('Question'));
     193    app.put('/api/questions/:id',
     194        ensureAuthenticated,
     195        makeDocPut_id('Question'));
     196    app.delete('/api/questions/:id',
     197        ensureAuthenticated,
     198        makeDocDel_id('Question'));
     199    app.get('/api/questions/categories',
     200        ensureAuthenticated,
     201        notImplemented);
     202
     203    // Surveys
     204    app.get('/api/surveys',
     205        ensureAuthenticated,
     206        makeDocsGet('Survey'));
     207    app.get('/api/surveys/:id',
     208        ensureAuthenticated,
     209        makeDocGet_id('Survey'));
     210    app.post('/api/surveys',
     211        ensureAuthenticated,
     212        makeDocPost('Survey'));
     213    app.put('/api/surveys/:id',
     214        ensureAuthenticated,
     215        makeDocPut_id('Survey'));
     216    app.delete('/api/surveys/:id',
     217        ensureAuthenticated,
     218        makeDocDel_id('Survey'));
     219
     220    // SurveyRuns
     221    app.get('/api/surveyRuns',
     222        ensureAuthenticated,
     223        makeDocsGet('SurveyRun'));
     224    app.get('/api/surveyRuns/:id',
     225        ensureAuthenticated,
     226        makeDocGet_id('SurveyRun'));
     227    app.get('/api/surveyRuns/:id/responses.csv',
    167228        ensureAuthenticated,
    168229        function(req, res) {
     
    183244            });
    184245        });
     246    app.get('/api/surveyRuns/:id/responses',
     247        ensureAuthenticated,
     248        function(req,res) {
     249            var id = req.params.id;
     250            var url = '_design/responses/_view/by_surveyrun?key='+JSON.stringify(id);
     251            couch.get(url).then(function(result){
     252                var responses = _.map(result.rows, function(item) { return item.value; });
     253                res.send(200, responses);
     254            }, function(error){
     255                res.send(404, {error: "Cannot find responses for survey run "+id});
     256            });
     257        });
    185258   
     259    // Responses
     260    app.get('/api/responses',
     261        ensureAuthenticated,
     262        makeDocsGet('Response'));
     263    app.get('/api/responses/:id',
     264        ensureAuthenticated,
     265        makeDocGet_id('Response'));
     266    app.post('/api/responses',
     267        ensureAuthenticated,
     268        makeDocPost('Response'));
     269    app.put('/api/responses/:id',
     270        ensureAuthenticated,
     271        makeDocPut_id('Response'));
     272    app.delete('/api/responses/:id',
     273        ensureAuthenticated,
     274        makeDocDel_id('Response'));
     275
    186276    return app;
    187277
    188 };
     278}
    189279
    190280function responsesToVariables(responses) {
  • Dev/trunk/src/server/bin/heroku.js

    r479 r481  
    44console.log("Running on",env.couchServerURL);
    55
    6 configCouch(env.couchServerURL)
    7 .then(function(){
    8     var app = require('../app').App({
    9         couchDbURL: env.couchDbURL
    10     });
    11 
     6require('../app').App({
     7    couchDbURL: env.couchDbURL
     8}).then(function(app){
     9    configCouch(env.couchServerURL);
     10    return app;
     11}).then(function(app){
    1212    app.listen(env.port, function() {
    1313        console.log('Listening on port',env.port);
  • Dev/trunk/src/server/config/couchdb-schema.json

    r480 r481  
    11{
    22  "title": "QED Object Schema",
     3  "version": "1",
    34  "type": "object",
    45  "oneOf": [
     
    1112        "_id": { "type": "string", "pattern": "schemaInfo" },
    1213        "_rev": { "type": "string", "optional": true },
    13         "version": { "type": "string", "pattern": "1" }
     14        "version": { "type": "string" }
    1415    },
    1516    "additionalProperties": false
Note: See TracChangeset for help on using the changeset viewer.