Share data models in Mongoose with your Frontend

In order to share a data models between technologies (ex: backend and frontend), the languages need to interpret the data to a common format. Most of the time, this boils down to converting/extacting a JSON object model.

Example of a shared JSON between the backend and frontend:

// file: shared/models/player.js
var Player {  
  league: { type: 'id', ref: 'League' },
  division: { type: 'id', ref: 'Division' },
  team: { type: 'id', ref: 'Team' },
  name: { type: 'string', default: '' },  
  created: { type: 'date', default: Date.now },
  updated: { type: 'date', default: Date.now }
};
export default Player;  

In case if you didn't notice, this looks exceptional similar to a Mongoose Schema Model. The main difference is the ObjectId is replaced with the string 'id' and all the other types are now relagated to strings too for consistency:

// file: api/utils.js
import mongoose from 'mongoose';  
var Schema = mongoose.Schema;  
import _ from 'lodash';

let mongooseify = function(json) {

  let result = {};
  _.map(Object.keys(json), (key) => {
    let property = _.cloneDeep(json[key]);
    let type;
    switch(property.type) {
      case 'id':
        type = Schema.ObjectId;
        break;
      case 'number':
        type = Number;
        break;
      case 'string':
        type = String;
        break;
      case 'date':
        type = Date;
        break;
      default:
        break;
    }
    result[key] = _.assign({}, property, {type});
  });

  return result;
};

Note: (This can be extended to add additional types)
And finally, create the Mongoose Model:

// file: api/models/player.model.js
'use strict';  
import mongoose from 'mongoose';  
var Schema = mongoose.Schema;  
import player from '../../shared/models/player';  
import utils from '../utils';

/**
 * Player Schema
 */
var PlayerSchema = new Schema(utils.mongooseify(player));

module.exports = mongoose.model('Player', PlayerSchema);
Comments powered by Disqus