title: ES6 Classes for Data Models
body: <p>I'm trying to use ES6 Classes to construct data models (from a MySQL database) in an API that I'm building. I prefer not using an ORM/ODM library, as this will be a very basic, simple API. But, I'm struggling to get my head around how to define these models.</p>
  
  <p>My data entities are (these are just some simplified examples):</p>
  
  <h2>CUSTOMER</h2>
  
  <h3>Data Model</h3>
  
  <pre><code>id
  name
  groupId
  status (enum of: active, suspended, closed)
  </code></pre>
  
  <h3>Private Methods</h3>
  
  <pre><code>_getState(status) {
      var state = (status  == 'active' ? 'good' : 'bad');
      return state;
  }
  </code></pre>
  
  <h3>Requests</h3>
  
  <p>I want to be able to do:</p>
  
  <ul>
  <li><p>findById: Providing a single customer.id, return the data for that specific customer, i.e. <code>SELECT * FROM customers WHERE id = ?</code></p></li>
  <li><p>findByGroupId: Providing a group.id, return the data for all the customers (in an array of objects), belonging to that group, i.e. <code>SELECT * FROM customers WHERE groupId = ?</code></p></li>
  </ul>
  
  <h3>Response Payloads</h3>
  
  <p>For each customer object, I want to return JSON like this:</p>
  
  <p><code>findById(1);</code>:</p>
  
  <pre><code>[{
      "id" : 1,
      "name" : "John Doe",
      "groupId" : 2,
      "status" : "active",
      "state" : "good"
  }]
  </code></pre>
  
  <p><code>findByGroupId(2);</code>:</p>
  
  <pre><code>[{
      "id" : 1,
      "name" : "John Doe",
      "groupId" : 2,
      "status" : "active",
      "state" : "good"
  },
  {
      "id" : 4,
      "name" : "Pete Smith",
      "groupId" : 2,
      "status" : "suspended",
      "state" : "bad"
  }]
  </code></pre>
  
  <h2>GROUP</h2>
  
  <h3>Data Model</h3>
  
  <pre><code>id
  title
  </code></pre>
  
  <h3>Requests</h3>
  
  <p>I want to be able to do:</p>
  
  <ul>
  <li>findById: Providing a single group.id, return the data for that specific group, i.e. <code>SELECT * FROM groups WHERE id = ?</code></li>
  </ul>
  
  <h3>Response Payloads</h3>
  
  <p>For each group object, I want to return JSON like this:</p>
  
  <p><code>findById(2);</code>:</p>
  
  <pre><code>{
      "id" : 2,
      "title" : "This is Group 2",
      "customers" : [{
          "id" : 1,
          "name" : "John Doe",
          "groupId" : 2,
          "status" : "active",
          "state" : "good"
      },
      {
          "id" : 4,
          "name" : "Pete Smith",
          "groupId" : 2,
          "status" : "suspended",
          "state" : "bad"
      }]
  }
  </code></pre>
  
  <p><hr /></p>
  
  <h1>Requirements:</h1>
  
  <ul>
  <li>Must use ES6 Classes</li>
  <li>Each model in its own file (e.g. <code>customer.js</code>) to be exported</li>
  </ul>
  
  <p><hr /></p>
  
  <h1>Questions:</h1>
  
  <p>My main questions are:</p>
  
  <ol>
  <li>Where would I define the data structure, including fields that require data transformation, using the private methods (e.g. <code>_getState()</code>)</li>
  <li>Should the <code>findById</code>, <code>findByGroupId</code>, etc by defined within the scope of the class? Or, should these by separate methods (in the same file as the class), that would instantiate the object?</li>
  <li>How should I deal with the case where one object is a child of the other, e.g. returning the <em>Customer</em> objects that belongs to a <em>Group</em> object as an array of objects in the <em>Group</em>'s <code>findById</code>?</li>
  <li>Where should the SQL queries that will connect to the DB be defined? In the <code>getById</code>, <code>getByGroupId</code>, etc?</li>
  </ol>
  
  <hr>
  
  <h2>UPDATE!!</h2>
  
  <p>This is what I came up with - (would be awesome if someone could review, and comment):</p>
  
  <h3>CUSTOMER Model</h3>
  
  <pre><code>'use strict';
  
  class Cust {
    constructor (custData) {
      this.id = custData.id;
      this.name = custData.name;
      this.groupId = custData.groupId;
      this.status = custData.status;
      this.state = this._getState(custData.status);
    }
  
    _getState(status) {
      let state = (status  == 'active' ? 'good' : 'bad');
      return state;
    }
  }
  
  exports.findById = ((id) =&gt; {
    return new Promise ((resolve, reject) =&gt; {
      let custData = `do the MySQL query here`;
      let cust = new Cust (custData);
      let Group = require(appDir + process.env.PATH_API + process.env.PATH_MODELS + 'group');
      Group.findById(cust.groupId).then(
        (group) =&gt; {
          cust.group = group;
          resolve (cust)
        },
        (err) =&gt; {
          resolve (cust);
        }
      );
    });
  });
  </code></pre>
  
  <h3>GROUP Model</h3>
  
  <pre><code>'use strict';
  
  class Group {
    constructor (groupData) {
      this.id = groupData.id;
      this.title = groupData.title;
    }
  }
  
  exports.findById = ((id) =&gt; {
    return new Promise ((resolve, reject) =&gt; {
      let groupData = `do the MySQL query here`;
      if (id != 2){
        reject('group - no go');
      };
      let group = new Group (groupData);
      resolve (group);
    });
  });
  </code></pre>
  
  <h3>CUSTOMER Controller (where the Customer model is instantiated)</h3>
  
  <pre><code>'use strict';
  
  var Cust = require(appDir + process.env.PATH_API + process.env.PATH_MODELS + 'cust');
  
  class CustController {
    constructor () {
    }
  
    getCust (req, res) {
      Cust.findById(req.params.id).then(
        (cust) =&gt; {
          res(cust);
        },
        (err) =&gt; {
          res(err);
        }
      )
    }
  }
  
  module.exports = CustController;
  </code></pre>
  
  <p>This seems to be working well, and I've been able to use <code>Class</code>, <code>Promise</code> and <code>let</code> to make it more ES6 friendly.</p>
  
  <p>So, I'd like to get some input on my approach. Also, am I using the <code>export</code> and <code>required</code> features correctly in this context?</p>