Flexure: A Lightweight Model Framework for Ember.js

Article summary

Ember Data is ambitious and does a lot of heavy lifting for you, which requires that it makes some big assumptions. It assumes you need an identity map, object relationship management, dirty state tracking, and that your interaction with your server is primarily or entirely CRUD operations.

I recently worked on a project where these assumptions didn’t fit, and I was in a tough spot. While Ember Data has a handful of alternatives, they all share these assumptions. I had to choose: I could use Ember Data and fight it along the way, or I could roll without it at the cost of spending time implementing or copying functionality that Ember Data provides for free.

Reluctantly, I chose to run without Ember Data. By the time the project finished, I realized that what little infrastructure I built up could easily be reused as a lightweight Ember Data alternative. I’ve cleaned it up a bit and decided to release it as Flexure.

What is Flexure?

When you’re writing an Ember app without Ember Data, there are really just two areas that could benefit from some infrastructure building.

1. Semantic Server Interactions

The first area is interacting with your server. For this, Flexure includes a thin wrapper around making async JSON calls to the server. The benefit in this approach is that you can model your thinking and interactions with the server in a more semantic way.

For example, instead of setting a flag on your model and implicitly knowing your server will do the required work, you could tell it “process this data” or “perform this action”. The tradeoff is that you do need to manually define how to CRUD with your API.

2. Objects as Competent Models

The second, more interesting area involves providing you with Ember objects you can treat as competent models throughout your controllers and templates. To accomplish this, Flexure includes:

  • A way to define the structure of your models, including types of attributes
  • Enforcing/coercing the type of certain attributes
  • Simple relationships: by defining a property as hasOne, hasMany, or hasPolymorphic. No inverse relationships are supported, because there is no identity map. If you attempt to set a relationship property to a non-ember object, it will automatically be converted into the appropriate model object.
  • Setting and clearing error flags on your models
  • Support for serializing and deserializing your objects into JSON.

That’s the entire scope of the library. For information on how to use it, check it out on github.

Wrapping up

If Ember Data is a good fit for your app, you should use it. But if it doesn’t fit your needs, however, I hope Flexure can help bridge the gap between your Ember app and your server API, so you aren’t conflicted between rolling your own and using a framework that doesn’t fit.
 

Conversation
  • Scott S says:

    First of looks like a great project! I think I’ve finally found something which can make my app work with Ember! But before I dive right in I have a couple questions:

    1. To access findPerson() would it be this.api.findPerson(name) ?
    2. Am I correct in understanding that there really isn’t even a minimalistic sort of “store”, and in my case where I only need to access models previously created via this.models.make("model", data) I’d need to implement it?

    Any help would be appreciated. I really think Flexure will allow me to use Ember for my app without feeling like I’m force-fitting Ember and my app together!

    • Chris Farber Chris Farber says:

      Thanks, Scott. To answer your questions:

      1. Yep. Your API object would get injected into your routes and controllers by default, or if you need it elsewhere you could pull “api:application” out of the DI container.
      2. That’s correct. Trying to cache data in the application would require making assumptions about apps building off of it. It’s also somewhat at odds with not having an identity map.

      I hope you find flexure useful! Feel free to post any issues you run into on github.

  • Comments are closed.