I really admire Netflix's ability to put together developer documentation for their open source projects. I think it reflects well on their engineering culture.
I was similarly impressed when I was reading the documentation for Hystrix, which seems to share some functionality with Falcor, like request batching and caching.
The path syntax is very readable and obviously plays to JavaScripts strengths as a dynamic language. However, I would gladly pay the cost of more cumbersome syntax to recover static analyzability through a tool like Flow or TypeScript. With Observables in particular, the ability to track the type of the value inside the Observable is really convenient.
I'm yet to come across a data layer for JS that plays nicely with Flow. Even Facebook's Flux struggles with it. I've been trying to work on my own implementation of the "Flux" architecture (unidirectional data flow), but I'm curious whether you know any decent "model" layers that work nicely in the weird statically-typed "JS" world?
I have been following the falcor announcements, presentations and discussions for a few months. I am really impressed at what a good job the Netflix team has done with introducing the json graph concepts, I've learned a lot it regardless of falcor. Kudos Netflix!
I really like the concepts and client/server model. If it is performant, it will be fun to see persistent videogame worlds written through falcor. To that end, would it be possible/effective to hang parts of the graph off of WeakMap so that big, not recently used parts of the graph are allowed to fall away? (Perhaps that is how it works right now, I haven't had a chance to look at the source code, pardon my ignorance...)
how have you been following this? I'd like to look at the json graph concepts you're talking about and having the discussion to go along with it would be very helpful.
This makes so much sense, after learning about Relay/GraphQL I was wondering who else was working on something like it, it appears Netflix is one of them :)
I think Falcor is conceptually interesting, but after reading some of the documentation and project code, I don't want to use it (at this point).
The library bills itself as "middleware", but it looks more like an application framework. I don't see how this would cleanly fit with other application frameworks, as it appears that you have to use Falcor models, routers, and datasources.
The project's code is concerning in a few ways: it's a large codebase, it reads more like C++ than JavaScript, and there's not enough comments. In my experience, successful JavaScript libraries are: small, use JS conventions, and have well-documented source code.
It's great that they are releasing open-source software, though. I hope that this project evolves into something that I want to use.
What's an example of the C++ conventions you're referring to? I'm looking at the source now trying to identify them. I don't see them. Looks javascripty to me.
It's definitely designed to be used in a RESTful-esque situation (the reference keys are a type/id tuples), but that's the dominant JSON use case anyway.
For an example of why you'd want type/id tuples over JSOG's plain string @id -- while in the given JSOG example, all items are People, referencing an Address object from Sally (so that Bob can deliver her gift) introduces a potential conflict between Address @id: 1 and Person @id: 1. To disambiguate, you could of course prefix all "@id" value strings with e.g. "address-" or "person-", but then you've just re-invented JSON-API's solution, while making your @id not a real id (not usable in cases like e.g. `api.example.com/resource/<id>`, etc.).
The other solution is to say that JSOG @id's are only for use in one response parsing situation, and could be discarded afterwards. But that seems like quite a waste -- what if e.g. your API wanted to be able to send @id references over the wire without the overhead of sending the whole referenced object?
I agree that the type/id pair is quite helpful when reading the graph! Interestingly, this does have the effect of limiting you to N top-level types, but I don't actually think that's a big deal. Most applications, if you break them down, only have like 3 real types (one of which is always "user").
JSOG solves one particular, widespread problem - reconstituting an object graph on the other side of a wire. As you said, the information is only meaningful during the exchange. JSOG isn't trying to solve some greater notion of object identity; that's your application's business.
There are no paths to evaluate, just unique synthetic ids. The JSOG transmutation process is a simple recursive function; most of the implementations are just a handful of lines of code.
This seems interesting. Given Netflix's admitted love of RX [Reactive Extensions] I'm somewhat curious if there is a design reason that this uses Promises instead of (RxJS/Bacon/...) Observables? At first skim this seems like it could be even more useful as an Observable model.
I'm also curious if there is a design reason they aren't using ES5 defineProperty/ES6 property syntax over get()/set()?
Interestingly enough, we actually return Observables. The model returns a Model Response, which inherits from Observable. It also adds a "then" method which returns a promise when called.
The primary advantage of using the Observable's "subscribe" method instead of "then" is that you can cancel a request. Netflix makes heavy use of this feature. For example when quickly browsing through titles, we may cancel the request for data that you are no longer looking at.
That's very good to know. All of the examples I saw in the documentation were using the Promise "then" and I didn't see any mention that they were in fact returning Observables.
If I may suggest it, perhaps you might add this a bit more explicitly to the documentation including possibly an example or two that makes use of them as Observables?
I've used a similar approach for Flask-Potion, a REST API framework (http://potion.readthedocs.org/). References are JSON objects in the format {"$ref": uri}, which makes them exceedingly simple to fetch and cache.
Some early ideas have already hit the repo[1]. David Nolen has been focused on ClojureScript bootstrapping work[2] of late, but I expect he'll get back to Om Next in the coming weeks.
This is really interesting and welcome contribution in an important space. Three features that would make it compelling:
1. Offline. Making the local datastore as "invisible" as the memory cache and the cloud - keeping everything in sync under the hood.
2. Push. Notifying clients when changes occur.
3. Diff. Efficiently handling changes in larger values.
I realise none of these are central to the challenge they faced, and congratulate them on an elegant solution for their situation.
"Falcor automatically traverses references in your graph and makes requests as needed."
This seems like it could be as much of a curse as a blessing. I hope 1.0 ships with a good development/debug mode to gauge the efficiency auto-generated requests.
Falcor engineer here. In short, we don't expose the cache's structure directly through any of the public methods. While we don't lock you out of your own data if your JSON value is a complex Object (it's wrapped inside an Atom - http://netflix.github.io/falcor/doc/global.html#Atom), any branches returned from get/set/call are separate Objects.
I disagree, though maybe I could see your point if you are unfamiliar with The Never-ending Story. Even then, they are in different spaces so a mental name collision seems unlikely.
This is great work, and neighbors very closely to what I am doing with http://github.com/amark/gun. But the caveat of Falcor is that it does not have realtime updates (unless they have since changed this, please let me know). I think this will be an Achilles heel for their architecture, so I hope they improve on this. Otherwise, really exciting news!
I was similarly impressed when I was reading the documentation for Hystrix, which seems to share some functionality with Falcor, like request batching and caching.
The path syntax is very readable and obviously plays to JavaScripts strengths as a dynamic language. However, I would gladly pay the cost of more cumbersome syntax to recover static analyzability through a tool like Flow or TypeScript. With Observables in particular, the ability to track the type of the value inside the Observable is really convenient.