Skip to content

Instantly share code, notes, and snippets.

@intabulas
Last active January 13, 2016 18:33
Show Gist options
  • Save intabulas/07d981d412f53a4da3a1 to your computer and use it in GitHub Desktop.
Save intabulas/07d981d412f53a4da3a1 to your computer and use it in GitHub Desktop.

Thoughts on Developing with Nodal

As I was starting to put together an all encompasing example app with data, I encountered things that I think new developers might stumble on and (hopefully not) possibly be turned off by.

Some of my thoughts are specifc to an application vs api nodal app and I will try to indicate as such

NOTE: A living gist which each item its own markdown file

One Controller One Endpoint

Applies to: Application and Api

I appreciate the lack of controller#method routing (ala rails) it makes stuff messy, but considering folks are coming from platforms that either support that flexibility or (go as an example) let you define routes and map them to methods as you see fit. I think the solution here is both good documentation both on api and implementations but also philosophy. Good example apps will also be help here

Scenario:

I have a single database of content. For the API portion of the app I want to have full CRUD on those entries. So for this the nodal g:controller V1 --for:Sighting works greate.

For the UI portion of the app I want a differnt slice of data. In this example I want an API endpoint I can make an XHR request to that will give me all the distinct states of the us in the dataset and the count of each that exist as a response:

{ 
  "CA": 5, 
  "WA": 6
}

Due to the current way the router works there is no way to add a method to the V1Sightings controller to provide that data, one must create a new controller for this.

Its not obvious that to get a namespace for a non crud controller its nodal new g:controller V1/MyNewController given the way to build one for a model --for:<Model> does magic to do the same thing. I think more docs or even a general how to use the cli video would be a good thing

I think it would be great to have examples and docs to explain how to manually structure the routes to at least have context in the url. Maybe even have the generator support this. I know the video explains the routing is a fall though, but given routes are appended by the generator, it might not be obvious how to manually restructure

ie:

  router.route(/^\/v1\/sightings\/statistics\/?/, V1SightingsStatisticsController);
  router.route(/^\/v1\/sightings\/?/, V1SightingsController);

If that made sense, I think the method of adding api endpoints to a resource that aren't crud methods needs to be documented well so folks understand that. I also think g:controller should allow for a namespace without the need for --for

This also might re-ignite the conversation about to regex or not to regex in the routes

doT Templates

Applies to: Application/Branding

I love doT templates and have used it in previous projects in the day job. Most folks are coming from erb or haml or even handlebars/ and might be put off by them. They do have alot of benefits and some limitations. I think in this case, more documentation on why it was chosen would be helpful. Maybe also an issue to support plugable tempalating in the future.

One of doT's limitations is layout support and can tend to lead to alot of copy/pasta in templates. You can acomplish layouts a little crazily

<!DOCTYPE html>
<html>
  <body>

    <div class="container">
      {{= this.partial(data.content) }}
    </div>
  </body>
</html>
module.exports = (function() {

  'use strict';

  const Nodal = require('nodal');

  class IndexController extends Nodal.Controller {

    get() {

      this.render(
        this.app.template('layout.html').generate(
          this.params,
          {
            name: 'App Name',
            content: 'index.html'
          }
        )
      );

    }

  }

  return IndexController;

})();

Maybe the nodal render method can take a layout as a param and acomplish this under the covers given a strict guideline for how to write the layout. Let template take a optional second param (if undef, no layout) and make a template param like content or yield or sort of reserved prop for templates

module.exports = (function() {

  'use strict';

  const Nodal = require('nodal');

  class IndexController extends Nodal.Controller {

    get() {

      this.render(
        this.app.template('index.html', 'layout.html').generate(
          this.params,
          {
            name: 'App Name'
          }
        )
      );

    }

  }

  return IndexController;

})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment