Enterprise and Mobile Web

Enterprise and Mobile Web

The mobile web is the intersection of mobile and cloud computing trends for many large companies. Fragmented device landscapes require a universal solution to their mobile pains, and apps built with tools like Backbone, HTML5, and backend as a service are uniquely positioned to provide that solution.

F70874714f4bb31b2ab4b6c70de39b04?s=128

Dave Wasmer

August 01, 2013
Tweet

Transcript

  1. Enterprise & Mobile Web BackboneConf - August 2013 - @davewasmer

  2. WARNING

  3. None
  4. #notsexy

  5. #actualrevenue

  6. Back Story Modularity Caching Offline Security

  7. Postgres Rails API Client (Backbone) Basic Backbone Stack

  8. Typical Enterprise Stack Salesforce SAP Sharepoint Splun k WebSphere Drupal

    Active Directory MobileIron VMwar e
  9. Mobile CRM Accounting ERP Call Center E

  10. None
  11. CRM Accounting ERP Call Center E backbone- associations memento marionette

    requirejs deep-model backbone-sap
  12. Back Story Modularity Caching Offline Security

  13. Backbone View

  14. var Account = Backbone.Model.extend({...}) ! becomes var Account = Kinvey.Backbone.Model.extend({...})

  15. Kinvey.Backbone.Model = Backbone.Model.extend(ModelMixin);

  16. Kinvey.Backbone.ModelMixin = _.extend({}, SyncMixin, {...})

  17. var BlogPost = Backbone.AssociatedModel.extend({ ! relations: [ { type: Backbone.Many,

    key: 'comments', relatedModel: BlogPostComment } ] ! });
  18. var BlogPost = Backbone.AssociatedModel.extend({ ! goto: function() { Router.navigate(“posts/” +

    this.id); }, ! // relations ... });
  19. None
  20. var BlogPost = Backbone.AssociatedModel.extend({ ! goto: function() { Router.navigate(_.result(this, ‘getResourceUrl’));

    }, ! getResourceUrl: function() { return “posts/” + this.id; }, ! // relations ... ! });
  21. var BaseModel = Backbone.AssociatedModel.extend({ ! goto: function() { Router.navigate(_.result(this, ‘getResourceUrl’));

    }, ! getResourceUrl: function() { throw new Error(‘no resource url given’); } ! }); ! var BlogPost = BaseModel.extend({ ! // relations ...
  22. var Author = BaseModel.extend({ ! // ... ! });

  23. var BaseModel = Backbone.AssociatedModel.extend({

  24. var BlogPost = Backbone.AssociatedModel.extend({ ! // relations ... ! });

    ! var ResourceRoutingMixin = { goto: function() { Router.navigate(_.result(this, ‘getResourceUrl’)); }, getResourceUrl: function() { throw new Error(‘no resource url given’); } } _.extend(BlogPost.prototype, ResourceRoutingMixin);
  25. Back Story Modularity Caching Offline Security

  26. None
  27. Back Story Modularity Caching Offline Security

  28. var db; ! var openRequest = indexedDB.open('cachedb'); ! openRequest.onsuccess =

    function(e) { db = openRequest.result; }
  29. var CachableModel = Backbone.Model.extend({ ! name: 'books' ! fetch: function(options)

    { // ... read from cache } ! });
  30. fetch: function(options) { if (options.useCache) { var transaction = db.transaction(this.name);

    var store = transaction.objectStore(this.name); var query = store.get(this.id); query.onsuccess = function(e) { this.set(query.result); options.success(this, null, options); } Backbone.Model.prototype.fetch.apply(this, arguments); } }
  31. fetch: function(options) { if (options.useCache) { var transaction = db.transaction(this.name);

    var store = transaction.objectStore(this.name); var query = store.get(this.id); query.onsuccess = function(e) { this.set(query.result); options.success(this, null, options); } Backbone.Model.prototype.fetch.apply(this, arguments); } }
  32. fetch: function(options) { if (options.useCache) { var transaction = db.transaction(this.name);

    var store = transaction.objectStore(this.name); var query = store.get(this.id); query.onsuccess = function(e) { this.set(query.result); options.success(this, null, options); } Backbone.Model.prototype.fetch.apply(this, arguments); } }
  33. fetch: function(options) { if (options.useCache) { var transaction = db.transaction(this.name);

    var store = transaction.objectStore(this.name); var query = store.get(this.id); query.onsuccess = function(e) { this.set(query.result); options.success(this, null, options); } Backbone.Model.prototype.fetch.apply(this, arguments); } }
  34. Back Story Modularity Caching Offline Security

  35. save: function(data, options) { this.set(data, options); if (!navigator.onLine) { //

    write to local } else { // write to server } }
  36. save: function(data, options) { this.set(data, options); if (!navigator.onLine) { var

    transaction = db.transaction(this.name, 'readwrite'); var store = transaction.objectStore(this.name); var insert = store.put(this.attributes); insert.onsuccess = options.success; } else { // write to server } }
  37. save: function(data, options) { this.set(data, options); if (!navigator.onLine) { var

    transaction = db.transaction(this.name, 'readwrite'); var store = transaction.objectStore(this.name); var insert = store.put(this.attributes); insert.onsuccess = options.success; ! var toSave = transaction.objectStore('to-save'); var tracker = toSave.put({id: this.id, name: this.name}); ! } else { // write to server } }
  38. save: function(data, options) { this.set(data, options); if (!navigator.onLine) { var

    transaction = db.transaction(this.name, 'readwrite'); var store = transaction.objectStore(this.name); var insert = store.put(this.attributes); insert.onsuccess = options.success; ! var toSave = transaction.objectStore('to-save'); var tracker = toSave.put({id: this.id, name: this.name}); tracker.onsuccess = ?  ! } else { // write to server } }
  39. success = _.after(options.success, 2);  ! var transaction = db.transaction(this.name,

    'readwrite'); var store = transaction.objectStore(this.name); var insert = store.put(this.attributes); insert.onsuccess = success; ! var toSave = transaction.objectStore('to-save'); var tracker = toSave.put({id: this.id, name: this.name}); tracker.onsuccess = success;
  40. var sync = function() { var toSave = db.transaction('to-save').objectStore('to-save') toSave.openCursor().onsuccess

    = function(event) { var cursor = event.target.result; if (cursor) { save(cursor.value); cursor.continue(); } else { console.log('all done!'); } } }
  41. var save = function(lookup) { var id = lookup.id, name

    = lookup.name; var store = db.transaction(name).objectStore(name); ! store.get(id).onsuccess = function(event) { record = event.target.result; fetch({name: name, record: record}) .then(function(serverCopy) { if (serverCopy.last_modified > record.last_modified) { resolveConflict({ server: serverCopy, client: record }); } }); } }
  42. Back Story Modularity Caching Offline Security

  43. Thanks! Hat tip to: Shubang Mani @bhangm Ryan Kahn @myztiq

    Morgan Bickle @morganbic
  44. Bonus Round

  45. Existing infrastructure

  46. Decoupling