Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Optimizing an API for Ember Data

Dan Gebhardt
February 15, 2013

Optimizing an API for Ember Data

Presentation given at Ember Camp 2013.

Dan Gebhardt

February 15, 2013
Tweet

More Decks by Dan Gebhardt

Other Decks in Programming

Transcript

  1. underscore_naming include root element id: 1, fk_id: 1, fk_ids: [1]

    conventions for including related data AM::S Conventions Saturday, February 16, 13
  2. DS.RESTAdapter Conventions underscore_naming include root element id: 1, fk_id: 1,

    fk_ids: [1] conventions for including related data Saturday, February 16, 13
  3. DS.RESTAdapter Conventions underscore_naming include root element id: 1, fk_id: 1,

    fk_ids: [1] conventions for including related data IDENTICAL TO ActiveModel::Serializers Saturday, February 16, 13
  4. class ApplicationSerializer < ActiveModel::Serializer # sideload related data by default

    embed :ids, include: true end A Sprinkling of Configuration Saturday, February 16, 13
  5. One-to-Many Relationships App.Post = DS.Model.extend({ title: DS.attr('string'), comments: DS.hasMany('App.Comment') });

    App.Comment = DS.Model.extend({ body: DS.attr('string'), post: DS.belongsTo('App.Post') }); Saturday, February 16, 13
  6. class PostSerializer < ApplicationSerializer attributes :title has_many :comments end class

    CommentSerializer < ApplicationSerializer attributes :body belongs_to :post end One-to-Many Relationships Saturday, February 16, 13
  7. { post: { id: 1, title: 'Ember is Omakase', comment_ids:

    [4, 5, 6] }, comments: [ {id: 4, post_id: 1, body: 'delicious!'}, {id: 5, post_id: 1, body: 'yuno turbolinks?'}, {id: 6, post_id: 1, body: 'is that a tentacle?'} ] } JSON One-to-Many Relationships Saturday, February 16, 13
  8. One-to-One Relationships App.User = DS.Model.extend({ name: DS.attr('string'), rights: DS.belongsTo('App.Rights') });

    App.Rights = DS.Model.extend({ admin: DS.attr('boolean'), user: DS.belongsTo('App.User') }); Saturday, February 16, 13
  9. class UserSerializer < ApplicationSerializer attributes :id, :name has_one :rights end

    class RightsSerializer < ApplicationSerializer attributes :id, :admin belongs_to :user end One-to-One Relationships Saturday, February 16, 13
  10. { user: { id: 1, name: '', rights_id: 2 },

    rights: [{ id: 2, admin: true, user_id: 1 }] } JSON One-to-One Relationships Saturday, February 16, 13
  11. One-to-None Relationships App.User = DS.Model.extend({ name: DS.attr('string'), rights: DS.belongsTo('App.Rights') });

    App.Rights = DS.Model.extend({ admin: DS.attr('boolean') }); Saturday, February 16, 13
  12. class UserSerializer < ApplicationSerializer attributes :id, :name has_one :rights end

    class RightsSerializer < ApplicationSerializer attributes :id, :admin end One-to-None Relationships Saturday, February 16, 13
  13. { user: { id: 1, name: '', rights_id: 2 },

    rights: [{ id: 2, admin: true }] } JSON One-to-None Relationships Saturday, February 16, 13
  14. Many-to-Many Relationships App.Post = DS.Model.extend({ title: DS.attr('string'), body: DS.attr('string'), tags:

    DS.hasMany('App.Tag') }); App.Tag = DS.Model.extend({ name: DS.attr('string'), posts: DS.hasMany('App.Post') }); Saturday, February 16, 13
  15. class PostSerializer < ApplicationSerializer attributes :id, :title, :body has_many :tags

    end class TagSerializer < ApplicationSerializer attributes :id, :name has_many :posts end Many-to-Many Relationships Saturday, February 16, 13
  16. { posts: [ {id: 1, title: 'Hello world', tag_ids: [11,

    12]}, {id: 2, title: 'Goodbye', tag_ids: [11, 13]} ], tags: [ {id: 11, name: 'announcements', post_ids: [1,2]}, {id: 12, name: 'happy', post_ids: [1]}, {id: 13, name: 'sad', post_ids: [2]} ] } JSON Many-to-Many Relationships Saturday, February 16, 13
  17. Many-to-None Relationships App.Post = DS.Model.extend({ title: DS.attr('string'), body: DS.attr('string'), tags:

    DS.hasMany('App.Tag') }); App.Tag = DS.Model.extend({ name: DS.attr('string') }); Saturday, February 16, 13
  18. class PostSerializer < ApplicationSerializer attributes :id, :title, :body has_many :tags

    end class TagSerializer < ApplicationSerializer attributes :id, :name end Many-to-None Relationships Saturday, February 16, 13
  19. { posts: [ {id: 1, title: 'Hello world', tag_ids: [11,

    12]}, {id: 2, title: 'Goodbye', tag_ids: [11, 13]} ], tags: [ {id: 11, name: 'announcements'}, {id: 12, name: 'happy'}, {id: 13, name: 'sad'} ] } JSON Many-to-None Relationships Saturday, February 16, 13
  20. { post: { id: 1, title: 'Ember is Omakase', comments:

    [ {id: 4, body: 'delicious!'}, {id: 5, body: 'yuno turbolinks?'}, {id: 6, body: 'is that a tentacle?'} ] } } JSON Serialized Embedded Data Saturday, February 16, 13
  21. class PostSerializer < ApplicationSerializer attributes :title has_many :comments, embed: :objects

    end class CommentSerializer < ApplicationSerializer attributes :body belongs_to :post end Embedded Data Serializers Saturday, February 16, 13
  22. Embedded Read-only Data App.Post = DS.Model.extend({ title: DS.attr('string'), comments: DS.hasMany('App.Comment')

    }); App.Comment = DS.Model.extend({ body: DS.attr('string') }); serializer.map('App.Post', { comments: {embedded: 'load'} }); Saturday, February 16, 13
  23. Embedded Writeable Data App.Post = DS.Model.extend({ title: DS.attr('string'), comments: DS.hasMany('App.Comment')

    }); App.Comment = DS.Model.extend({ body: DS.attr('string') }); serializer.map('App.Post', { comments: {embedded: 'always'} }); Saturday, February 16, 13
  24. { hobbit: {id: 1, name: 'Bilbo'} } { hobbitses: [

    {id: 1, name: 'Bilbo'} {id: 2, name: 'Frodo'} {id: 3, name: 'Samwise'} ] } JSON Custom Pluralization Saturday, February 16, 13
  25. { post: { id: 1, titleOfPost: 'Ember is Omakase' }

    } JSON Custom Keys Saturday, February 16, 13
  26. { post: { id: 1, title: 'Ember is Omakase', comment_ids:

    [4, 5, 6] }, post_comments: [ {id: 4, post_id: 1, body: 'delicious!'}, {id: 5, post_id: 1, body: 'yuno turbolinks?'}, {id: 6, post_id: 1, body: 'is that a tentacle?'} ] } JSON Custom Sideloading Saturday, February 16, 13
  27. Custom Transforms Adapter.registerTransform('excitableString', { serialize: function(value) { return value +

    '!'; }, deserialize: function(value) { return value.substring(0, value.length - 1); } }); App.Greeting = DS.Model.extend({ message: DS.attr('excitableString') }); Saturday, February 16, 13
  28. Custom URLs adapter.set('namespace', 'ember'); person = store.find(Person, 1); // =>

    /ember/people/1 adapter.set('url', 'http://api.ember.dev'); person = store.find(Person, 1); // => http://api.ember.dev/people/1 Saturday, February 16, 13
  29. Bulk Commits adapter.set('bulkCommit', true); store.createRecord(App.Person, {name: 'tomdale'}); store.createRecord(App.Person, {name: 'wycats'});

    store.commit(); // POST to /people // {people: [{name: 'tomdale'}, {name: 'wycats'}]} Saturday, February 16, 13
  30. Edge of Convention Pagination Authentication Sparse fieldsets Custom includes Polymorphism

    Creative Commons licensed by: _chrisUK Saturday, February 16, 13