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
640
Worker power!
dgeb
0
440
Modern Ember
dgeb
0
130
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
77
Introducing Ember Engines
dgeb
4
3.3k
Introducing JSON API
dgeb
5
660
Fault Tolerant UX
dgeb
4
860
Other Decks in Programming
See All in Programming
Mastering Developer Experience: A Roadmap for Success 【開発生産性Conference 2024】
findyinc
1
380
初心者がおさえておきたいAWS CDKのベストプラクティス 2024
konokenj
15
7.3k
Findy - エンジニア向け会社紹介 / Findy Letter for Engineers
findyinc
2
81k
CSC307 Lecture 11
javiergs
PRO
0
240
スクラムマスターって孤独じゃないですか?
yoshitaroyoyo
1
140
Rubyのパフォーマンスプロファイリングの改善 / Enhancing performance profiling for Ruby
osyoyu
1
410
社内 LT 会を発足し、アウトプット文化を醸成させるために考えたこと・やったこと / Starting internal LT meetings and fostering an output culture
mackey0225
3
120
How to use Macrobenchmark
veronikapj
0
160
OpenAI/Gemini APIを使って EPUBを翻訳するCLIツールをつくってみた
tomiyan
0
790
Cloudflare Workers x AWS Lambdaの組み合わせユースケース / Cloudflare Workers x AWS Lambda Combination Use Case
seike460
PRO
2
310
Google's Recipe for Scaling (Web) Security – LocoMocoSec 2024
lweichselbaum
0
170
Namespace on read
tagomoris
2
370
Featured
See All Featured
How to Think Like a Performance Engineer
csswizardry
4
590
[RailsConf 2023] Rails as a piece of cake
palkan
35
4.4k
The Cult of Friendly URLs
andyhume
75
5.9k
No one is an island. Learnings from fostering a developers community.
thoeni
17
2.8k
Building Flexible Design Systems
yeseniaperezcruz
323
37k
The Art of Programming - Codeland 2020
erikaheidi
48
13k
Fontdeck: Realign not Redesign
paulrobertlloyd
79
5.1k
What's in a price? How to price your products and services
michaelherold
239
11k
GitHub's CSS Performance
jonrohan
1026
450k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
44
4.7k
Ruby is Unlike a Banana
tanoku
96
10k
Code Review Best Practice
trishagee
58
16k
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