A maintainable UI architecture requires that our UI only contains the logic to render current app state and relay queries and mutations to the underlying data layer on the server (i.e. a maintainable UI must not contain any logic for deriving user intent or deriving app state, as either would necessarily encode business logic in the client.)
GraphQL allows us to do that by defining an application-level, UI-agnostic schema on the server that captures the types and relationships in our data, and wiring to data sources via resolvers that leverage our db's own query language or in-memory objects to resolve client-defined "queries" and "mutations" against the schema.
With each component in the UI component tree declaring its own data dependencies, GraphQL (with Relay or Apollo client in the browser) creates a projection of the server-side data model that maps directly to the UI component tree, thus allowing us to have an application-level, UI-agnostic model of our data on the server, while at once giving us and UI-specific projection of our app's state. Using Relay or Apollo the queries from our GraphQL client to the GraphQL server are composed in an efficient manner based on the aggregate data dependencies that are declared by each component in the UI component tree, thus eliminating redundant queries over the network.
Relay (and Apollo client) also allow for mutation events from the UI to propagate to the server, while keeping the projected app state in the UI in sync with the data on the server. Relay|Apollo can also update the UI when an external mutation (from another process/user) takes place on the server, via GraphQL subscriptions.
Given the UI's data dependencies are specified declaratively, the front end developer's job becomes a much more pleasant task of building the application-level, UI-agnostic GraphQL schema, building UI components and declaratively specifying their queries and mutations.
With GraphQL/Relay everyone, be them web, mobile or 3rd party developers, works with the same application-level, UI agnostic, server-side schema and declare their data dependencies at the UI component level, then have GraphQL in combination with Relay or Apollo et al take care of generating an efficient query, shaping the query result for consumption by the UI and keeping the projected app state in sync with the data on the server.
In one fell swoop, GraphQL/Relay (or Apollo Stack) eliminate a host of cost centers, conveniences and tools such as RESTful APIs, ORMs/ODMs (it should as it removes the need for manual denormalization/renormalization, unless you don't wish to ue SQL/NoSQL query syntax directly) and imperatively sync'd client caches. Client-side-only solutions like Redux (without GraphQL/Apollo) don't go deep enough, and as such end up putting app state and user intent derivation in the client, which means that business logic gets entangled in the client by design.
A deep architecture like GraphQL/Relay (and Apollo) allow us to make radical changes to our UI without a lot of rework on client and server, which is something that cannot be done with a shallow, client-side-only architecture.
###References
- [Building a GraphQL Server with Node.js and SQL] (https://www.reindex.io/blog/building-a-graphql-server-with-node-js-and-sql/)
More coming soon... 2. ###Updated 1:
(after a Twitter chat with @en_JS (Joseph Savona), one of the GraphQL/Relay developers at Facebook)
Any app state that is not sync'd to the db is not something that Relay encompasses right now, but there is an ongoing [discussion] (facebook/relay#114) for handling scenarios like client-side form validation and state updates from sources other than the db (e.g. websocket)
These important scenarios will be addressed according to the Relay Roadmap (https://github.com/facebook/relay/wiki/Roadmap):
-
API for resolving fields locally: #431.
-
Support querying & compiling client-only fields by extending the server schema, and a means for writing data for these fields into the cache: #114.
###Update 2:
@gaearon (Dan Abramov), author of Redux, was gracious enough to tweet this, and I give him a lot of credit for doing so.
Here is a section of the very long conversation that Dan started:
![twitter conversation] (http://i.imgur.com/BD2Wu5m.png)
###Update 3:
My follow up conversation with Dan Abrahmov below
![twitter follow up] (http://i.imgur.com/43lsGJo.png)