Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Optimizing an API for Ember Data
Search
Dan Gebhardt
February 15, 2013
Programming
32
4.5k
Optimizing an API for Ember Data
Presentation given at Ember Camp 2013.
Dan Gebhardt
February 15, 2013
Tweet
Share
More Decks by Dan Gebhardt
See All by Dan Gebhardt
An Introduction to the JSON:API Specification
dgeb
5
630
Worker power!
dgeb
0
430
Modern Ember
dgeb
0
120
The Future of Data in Ember
dgeb
0
380
Give Apps Online Superpowers by Optimizing them for Offline
dgeb
2
180
Overview of Orbit.js
dgeb
0
74
Introducing Ember Engines
dgeb
4
3.3k
Introducing JSON API
dgeb
5
640
Fault Tolerant UX
dgeb
4
840
Other Decks in Programming
See All in Programming
Long journey of Ruby standard library RubyKaigi 2024
andpad
2
200
FoodGram
iseruuuuu
0
230
『WordPressコミュニティで学ぶ』OSS貢献の多様性
ippey
0
220
Open AI APIを使う前に知っておきたいアカウントTier の話
akki_megane
0
130
slog登場に伴うloggerの取り回し手法の見直し / kamakura.go #6
arthur1
0
120
仕様と実装で学ぶOpenTelemetry
drumato
2
920
freeeのエンジニアが 就活で出そうな コーディングテストを 解説してみる
freee
1
160
ソースコードを美しくたもつために ~コードレビューの認知限界を突破し、年間400リリースを達成する~
kotauchisunsun
1
730
Embedding it into Ruby code
soutaro
1
300
CQRS meets modern Java
simas
PRO
2
470
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
1
120
TypeScriptのパフォーマンス改善
yajihum
14
5k
Featured
See All Featured
Unsuck your backbone
ammeep
664
57k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
352
28k
The Art of Programming - Codeland 2020
erikaheidi
43
12k
GraphQLとの向き合い方2022年版
quramy
33
13k
[RailsConf 2023] Rails as a piece of cake
palkan
28
4.1k
Put a Button on it: Removing Barriers to Going Fast.
kastner
58
3.1k
Fontdeck: Realign not Redesign
paulrobertlloyd
76
4.9k
Fantastic passwords and where to find them - at NoRuKo
philnash
39
2.5k
The Cost Of JavaScript in 2023
addyosmani
21
4k
Infographics Made Easy
chrislema
238
18k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
323
20k
Making Projects Easy
brettharned
109
5.5k
Transcript
Optimizing An API For Ember Data Dan Gebhardt Saturday, February
16, 13
Dan Gebhardt @dgeb Saturday, February 16, 13
Convention Configuration Saturday, February 16, 13
“Trivial choices are the enemy” - Yehuda Katz Saturday, February
16, 13
Ruby on Rails ActiveModel::Serializers Ember.js Ember Data Saturday, February 16,
13
Saturday, February 16, 13
“What” not “how” DRY Customizable ActiveModel::Serializers Saturday, February 16, 13
Ember Data In memory store Canonical records Multi-layered architecture Customizable
adapters / serializers Saturday, February 16, 13
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
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
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
class ApplicationSerializer < ActiveModel::Serializer # sideload related data by default
embed :ids, include: true end A Sprinkling of Configuration Saturday, February 16, 13
Relationships source: twitamore.com Saturday, February 16, 13
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
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
{ 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
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
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
{ user: { id: 1, name: '', rights_id: 2 },
rights: [{ id: 2, admin: true, user_id: 1 }] } JSON One-to-One Relationships Saturday, February 16, 13
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
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
{ user: { id: 1, name: '', rights_id: 2 },
rights: [{ id: 2, admin: true }] } JSON One-to-None Relationships Saturday, February 16, 13
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
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
{ 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
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
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
{ 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
Embedded Relationships Creative Commons licensed by: Subhash Chandra Saturday, February
16, 13
{ 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
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
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
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
Customizations Saturday, February 16, 13
{ 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
Custom Pluralization serializer.configure('plurals', { hobbit: 'hobbitses' }); Saturday, February 16,
13
{ post: { id: 1, titleOfPost: 'Ember is Omakase' }
} JSON Custom Keys Saturday, February 16, 13
Custom Keys serializer.map('App.Post', { title: {key: 'titleOfPost'} }); Saturday, February
16, 13
{ 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
Custom Sideloading serializer.configure('App.Comment', { sideloadAs: 'post_comments' }); Saturday, February 16,
13
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
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
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
Edge of Convention Pagination Authentication Sparse fieldsets Custom includes Polymorphism
Creative Commons licensed by: _chrisUK Saturday, February 16, 13
Resources https://github.com/dgeb/ember_data_example https://github.com/rails-api/active_model_serializers http://stackoverflow.com/questions/tagged/ember-data Saturday, February 16, 13