View
462
Download
2
Category
Preview:
Citation preview
Craig Smitham@craigsmitham
https://github.com/falcordotnet/falcor.net
FALCOR@NetflixUIE@falcorjs
Today• The (d)evolution REST at Netflix• Falcor• JSON Graph• Building .NET APIs with Falcor• Status and Next Steps
REST
The World Wide Web• Graph of Resources (WWW)• Each Resource has a Unique Identifier
(URL)• VERBs for transforming resource state
– GET– PUT– POST– DELETE
is a browsing problem.
http://www.netflix.com/genreLists?rowOffset=0&rowSize=5&colOffset=5&colSize=15&titleprops=name,boxshothttp://www.netflix.com/setRating?titleId=5&view=movieDetailPage
REST-less API
20101
Netflix’s RESTful APIhttp://www.netflix.com/genreList/12429
http://www.netflix.com/title/1601923
Title Resourcehttp://netflix.com/titles/95632123
{ id: 2523, name: “House of Cards”, boxshot: “http://…/018-192-x50.png”, rating: 5, bookmark: 52119562, director: “David Fincher”, // a few more fields}
REST Latency01: GET /genreLists02: GET netflix.com/titles/95632503: GET cdn01.netflix.com/072-192-x50.png04: GET netflix.com/titles/99233805: GET cdn03.netflix.com/018-192-x50.png06: GET netflix.com/titles/91273807: GET cdn09.netflix.com/651-70x50.png …27: GET netflix.com/titles/56182628: GET cdn23.netflix.com/018-70x50.png
Once the web was a place to get things.
Today the web is a place to do things.
Web Server Application Server
Web Pages serve small amounts of large resources.Web Apps serve large amounts of small resources.
http://www.netflix.com/genreLists?rowOffset=0&rowSize=5&colOffset=5&colSize=15&titleprops=name,boxshothttp://www.netflix.com/setRating?titleId=5&view=movieDetailPage
REST-less API
20101
Netflix’s RESTful APIhttp://www.netflix.com/genreList/12429
http://www.netflix.com/title/1601923
RPC
/genreList?pageSize=13x15 /search?text=house/genreList?pageSize=13x15 /search?text=netflix/titleDetails?id=342/titleDetails?id=342
RPC
RPC: No Cache Consistency
Title
Title
Title
PersonalizedGenre Lists
/genreLists ?page=4x4 &props=name,title
/getTitleDetails?id=3432
Same info, two different URLS!
REST
• Cache Consistency• Loose Coupling
RPC
• Small Message Sizes• Low Latency
?
FALCOR
What is Falcor?
Falcor is not a replacement for your Database, MVC framework,
or your Web Server.
Falcor fits into your existing stack,allowing the layers to
communicate more efficiently.
/model.json
An Async Model
/member.json/member.json?...
FALCORon
Live Coding a mini-Netflixwith Falcor
Netflix’s Domain Model is a Graph
JSON is for Trees.
“Suggestions for You”
“New Releases”
Genre Lists
id:956
id:956
Introducing JSON Graph
Building a Routed Model
/member.json
genres titlesratings
Falcor on the Server• Caching benefits of REST• Low-latency/Small message size of
RPC• Supports Function Calls
/member.json/member.json?path=titlesById[2344][“name”, “description”…”staffing”]
Show Detail Controller
<html></html>Show Detail View<div>{{ title.getValue(“name”)|async}}
{{ title.getValue(“description”)|async}} … {{ title.getValue(“staffing”)|async}}</div>
Related Titles
Falcor for .NET• Early alpha available now• https://
github.com/falcordotnet/falcor.net• OWIN middleware
– ASP.NET 5 support coming soon• Help and contributions from:
– Jafar Husain, Netflix– Pavel Vasek
Falcor.NET Router
public class NetflixRouter : FalcorRouter { public NetflixRouter(..., int userId) { Get["titlesById[{ranges:titleIds}]['rating']"] = async parameters => { List<int> titleIds = parameters.titleIds; var ratings = await ratingService.GetRatingsAsync(titleIds, userId); var results = titleIds.Select(titleId => { var rating = ratings.SingleOrDefault(r => r.TitleId == titleId); var path = Path("titlesById", titleId); if (rating == null) return path.Keys("userRating", "rating").Undefined(); if (rating.Error) return path.Keys("userRating", "rating").Error(rating.ErrorMessage); return path .Key("userRating").Atom(rating.UserRating) .Key("rating").Atom(rating.Rating); });
return Complete(results); };
Get["genrelist.mylist"] = async _ => { ... }; } }
OWIN Middleware (WIP)
public class Startup { public void Configuration(IAppBuilder app) { app.UseFalcor("/model.json", routerFactory: config => new NetflixRouter(...));
... } }
Bind to the Cloudvar model = new falcor.Model({ source: new falcor.HttpDataSource('/model.json')});
model.get('titlesById[2..5]["rating", "userRating"]') .then(logJson, logJsonError);
// Set up our model
// Query model asynchronously
// Handle results ...
When Should I Use Falcor?
Good Fit Poor Fit
Fetching large amounts of small resources (e.g. web components, JSON, metadata, etc.)
Fetching small amounts of large resources(e.g. web pages, images, files, etc.)
Aggregating heterogeneous services efficiently (e.g. microservices or loosley-coupled modules)
Fetching from a single back-end data source or service
Delivering responsive and capable end-user client experiences Systems integration and public APIs
Heterogeneous and evolving data access patterns (multiple devices, changing use cases)
Static websites
Consider the Falcor approach when you are developing a client/server architecture provides a rich data-driven interactive user experience.
Next Steps• Implement Set, Call• Support batchable service requests• Composable/distributed routers• Performance testing• Documentation• 1.0 milestone – Early 2016• Contributors welcome!
How to Get Involved• GitHub repository: https://
github.com/falcordotnet/falcor.net• Gitter Chat: https://
gitter.im/falcordotnet/falcor.net• Learning Resources: https://
github.com/falcordotnet/falcor.net/wiki/Learning-Resources
Recommended