reinventing web apis with falcor.net

Post on 14-Feb-2017

457 Views

Category:

Software

2 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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

top related