Handling with secure data: CRUD-Server and Ember-Data the best choice?


#1

Im working on an social app (multi-user) as well as the related backend (REST API) for that project.

Im wondering what is a good practice to handle the data-models. Since I thought i is the state of the art to use ember-data I based my whole construct so far on it.

Now im realizing, that Im getting into some trouble in the way I want to handle the data.

Lets say I have a route where I can create a new “Workgroup” or something. A “Workgroup” belongs to a “Office”-Record. My User has a List of many Workgroups.

User

name: DS.attr(‘string’), myGroups: DS.hasMany(‘workgroup’, {reverse: creator})

Workgroup

creator: DS.belongsTo(‘user’), office: DS.belongsTo(‘office’)

Office

workgroup: DS.hasMany(‘workgroup’)

On my route where I can create the new Workgroup, I have to chain a lot of steps to instanciate the models on the client side (in ember-data’s store) and save() them to the REST-Server. Like:

 store.find('user', curentUserID)
     .then(function(_currentUser){
  
     var newWorkgroup = store.createRecord('Workgroup' function(), {
        creator: _currentUser,
        office: null
      });
   
     newWorkgroup.save().then(...);
   
});

This is getting more and more complex when you see that you have also create a record for office in the same step and put it as a reference in the new ‘workgroup.office’-field (in that case simply ‘null’).

However when Im acting like that, all the business-logic of creating and manipulating models is putted into the client and just “saved” to the Backend which is acting like a CRUD-Server if you want to say so. The problem is, that this is horrible unsecure in my opinion since the client could send whatever he wants as IDs in the “relationship between the models” fields (he could save ID’s of workgroups in his own user-records ‘myGroups’-field of workinggroup-records which belongs to a complete different person for example).

Also since all three models up there have two-ways-relationships I have to write a lot of code (an a very long and ugly “then”-chain) to

  • get the user
  • create the workgroup
  • update the workgroup relationship (id) within the office-record
  • update the myGroups relationship (id’s) within the user-record (myWorkgroups)

In that case it may be not so hard to realize that. But in more complex usecases I have to handle with a big bunch of models at once I fear.

Therefore Im wondering if ember-data is a good choice for such a project. Do you have Ideas about that? Do you use ember-data or something else (maybe every model-action just running on server with an usecase fitting API like myserver.local:3000/api/createANewWorkgroup )


#2

Ember is for client side apps - you cannot rely on it for any security. If your api allows you to send the incorrect ids for this sort of stuff, you have a big problem. You need to make your api secure so that it only allows the things you want it to. For example, why are you allowing the user to be set on the client side at all? Surely only the server should be allowed to set that field for who created a record.

Ember data is just a wrapper around restful calls. So first figure out how you would do this with REST, and then use ember data to do that.

  • get the user ← Don’t do that, the server should set the user
  • create the workgroup ← fine, create a new workgroup record.
  • update the workgroup relationship (id) within the office-record ← why are you doing this here? If a workgroup belongs to an office, why haven’t you already set that office to the workgroup when you created it?
  • update the myGroups relationship (id’s) within the user-record (myWorkgroups) ← unless you want users to be able to assign their own groups, again this is a server side thing. Maybe you need to refresh your user from your server after creating a workgroup, or maybe not if that information is contained in the response from creating the record.

Therefore Im wondering if ember-data is a good choice for such a project. Do you have Ideas about that? Do you use ember-data or something else (maybe every model-action just running on server with an usecase fitting API like myserver.local:3000/api/createANewWorkgroup )

I would definitely advise to avoid this style of API as it is RPC not REST style, which is generally bad practice when it comes to HTTP. Sometimes you may need to use plain ajax instead of ember data but I can’t see why you need that here, it seems all you need is to create one record and save it, which ember data handles very well


#3

I model everything myself and use this simple store addon to share the primitive data structures across the app (array/object). It’s both ember 1.13/2.0/2.1 friendly

Using this store you could model a one-to-many like so

role: Ember.computed('all_roles.[]', function() {
    let belongs_to = this.get('belongs_to_role');
    return belongs_to ? belongs_to.objectAt(0) : undefined;
}),
all_roles: Ember.computed(function() {
    let store = this.get('store');
    let filter = function(role) {
        let user_ids = role.get('users') || [];
        return Ember.$.inArray(this.get('id'), user_ids) > -1;
    };
    return store.find('role', filter.bind(this), ['users']);
})

The role model would have a simple array of user pks essentially that help you map the one-to-many (nothing crazy). That’s the users string at the end of store.find (it breaks the computed property on the ArrayProxy)

The pro/and con is that you are in charge of all the data flow/ajax work in the application but honestly that’s not anything you couldn’t do from the sound of it :smile:

My routes fetch data using a repository (that does all the ajax work). If I break the json apart to build the models I use a deserializer object (that is injected in the repository). Here is a simple example app showing master/detail in it’s simplest form.


#4

I’d suggest checking out https://github.com/pixelhandler/ember-jsonapi-resources instead of Ember Data if you are (or can) use the JSON API spec. I think it’s a lot easier to manage relationships. Plus, if you use the jsonapi-resources ruby gem on a Rails backend, the setup is very easy!

Here’s the backstory on why @pixelhandler created it: http://pixelhandler.com/posts/my-battle-with-data-persistence-in-ember-apps