graphql (facebook), falcor (netflix) and odata and ...

There is a need in web client applications to query a server. Many people have been turned off by REST as the basis for an API because it requires them to navigate the explicit or implied schema on the server through a series of REST calls. Often the REST URL format is adhoc. The REST calls reflect the data architecture on the server and require orchestration into the object graph to retrieve the data. A more formal adherence to REST would include links in the response that eases this type of navigation but many RESTful APIs do not follow this model.

Along time ago, server side applications using ORM or just SQL tools ran into "how to pull an object graph" problem and never really solved it robustly although solutions exist. If the graph request was rigidly programmed into the object description, you would never be able to pull an ad-hoc object graph (that was not programmed into the ORM object annotations) easily and your client code would be littered with network database calls.

SQL addressed this by allowing you to specify the "schema" of the returned data but SQL is fairly limiting because the data you pull is eventually flattened into a one-level row. Graph database have had graph query languages for a long time, think neo4j and its graph query languages like cypher have worked to address graph database querying and contains a few artifacts that are highly specific to a node-edge  mental model.

If you are a web client programmer, you may wonder which one you should choose?

I cannot decide that for you in his blog, but you can think of the different APIs as all trying to achieve the same thing, that is, allowing you to specify the depth and traversal of properties in your object graph and return just the elements you need, in the form you need them. Here, the concept of "form" refers to returning the actual data or reference/links to the data where the data can be thought of as an object graph.

Odata supports full graph traversal and has a rich query language. The query is mostly contained in the URL making the data friendly to web caches. It is a rich and general purpose query language. The price you pay is in composing the query URLs, which can be complex, as well as interpreting the data that is returned, which can also be more complex. Of course, you can just use the parts of Odata you want, let the defaults occur, and then use that model to engage Odata on your client. Also, you can create some functions that create the query once you know what you want. If you take this simplified approach, its fairly easy. odata supports concepts similar to those found in a RDBMS including calling what looks like stored procedures. If these are not relevant to your backend database, e.g. an odata interface over another graph db, then you can ignore that feature.

Facebook came out with graphql, a json oriented specification model for querying backend data sources. Similar to odata, you can write fairly general queries. odata has a richer filter and specification language for pulling data, but graphql is very similar to odata. graphql embeds the knowledge of the graph in a json like structure unlike odata which embeds the query in the URL. This implies that architecturally, you are not forcing a URL-based model to access the server and invent your own protocol. Of course, its fairly easy to just embed the URL in your body anyway and have the server retrieve the data using that URL just as if you had specified a json body. Many people forget the flexibility you have with HTTP payloads.

Falcor, from Netflix, is similar to odata and graphql but simplifies the nature of the filters and constraints on the data that is returned. For some applications, this difference may not be significant and when it is not significant, the falcor approach can simplify the data manipulation and query formation on the client side.

All of the libraries seek to create a more general purpose query language that navigate an object graph. This problem has been solved before in different ways but these libraries today do take into account web architectures and today's client side programming languages and tools. graphql continues to move in the direction of odata's capabilities in its own "graphql specific way."

Personally, I have found that I rarely specify more queries that go more than 4-5 object levels deep in my object graph and graphql and odata are about the same. I do find the richer query language in odata to be more convenient at times when the server supports odata.

Of course, all of these approaches create special DSLs for querying that take you out of the language you program your client in and require you to handle the data using code. While other companies have pioneered embedding database query DSLs into programming languages (ABAP, SQL, LINQ), the approaches listed above still require you to navigate that impedance mismatch to some degree.


Popular posts from this blog

zio layers and framework integration

typescript and react types

dotty+scala.js+async: interesting options