graphitation
graphitation copied to clipboard
Import vision doc from TMP
NOTE: This needs updating based on latest packages and new thinking.
nova-facade-react-graphql
This package aims to provide a React component tree with the means to retrieve data from an abstract GraphQL client, allowing the components to focus on the generic UI needs rather than host specific data resolving.
The following details are not stricly related to just GraphQL in the context of Nova, but until this effort outgrows the current Nova goals, this seems as good a place as any to give this overview.
Flavours:
We want high value components to be shareable with a wide range of host applications, however not all host applications are equal in the data layers—let alone in their offering of a GraphQL layer. Similarly, not all high value components have the same needs of a GraphQL client/layer. Thus there's a need to provide a matrix of runtime/build-time flavours.
Runtime flavours:
-
At a baseline it will provide an unopiniated way to fetch a fat query operation, leaving distribution of the data among the component tree up to the component implementors.
-
However, it will also come with an opinionated way of 'fragmentizing' data requirements, such that a component can express its own data needs using a co-located GraphQL fragment and remain fully isolated from its parents' and children's needs, thus aiming to improve maintenanability of a large component tree and making it easier to avoid over/under fetching of data.
For more information on this concept, see for example this article.
Note that this is nothing more than a way to organize code and requirements; at runtime there is no promise that the implementation needs to do anything more than pass through the data from the parent.
-
With #2 in place, this fragmentized approach will allow us to optimize generic concerns that a larger application has, such as avoiding unnecessary re-renders while staying in-sync with the data it represents, as it exists in a normalized store.
For more information on this topic, see for example this article.
Build-time flavours:
-
A high value component targeting any of the runtime flavours can use the provided high-performance CLI tool (
nova-facade-graphql-compiler
) to codegen TypeScript typings for its GraphQL query operations. However, the opinionated runtime flavours are required to do so due to the specialized manner in which the typings are emitted to enforce data-masking. -
A host application that can statically know about all operations that can be performed could compile away any GraphQL schema request execution. Thus entirely doing away with parsing and validating of documents, finding the set of resolvers needed to resolve the request, etc.
-
A high value component tree that has no normalized store needs could be compiled in such a way that no little to no overhead exists at runtime when distributing resolved data along the component tree.
-
Likewise, a high value component tree that does have normalized store needs could be compiled in a way that does come with runtime overhead, but would aim to reduce the need for performance optimizations work in every component.
Work items for a first naive version to allow building of the AppBar
- [x] Provide a means to perform a lazy query operation, meaning to initiate a query during rendering of a component tree. (Runtime flavour #1.)
- [x] Provide a way to fragmentize React components, meaning a component's data requirements can be co-located with the component, rather than living at the root of the component tree. (Runtime flavour #2.)
- [x] Provide a way to codegen TypeScript typings for operation/fragment documents with opaque data-masking for fragment references.
- [x] Provide a way for host to inject dependencies.
- [ ] Provide a way to easily (unit) test a fragmentized component tree.
- [ ] Possibly provide a babel transform that can inline the
graphql
tag AST at build time. The existing babel-plugin-graphql-tag transform relies on thegraphql-tag
package, which is normally known to add AST of referenced fragments, rather than referring to the existing AST objects. We don't want that and are avoiding it currently in the uncompiled use of thegraphql
tag. - [ ] Possibly provide a simple built-in way to check fragment data to avoid unnecessary re-renders.
Work items for the longer term
- [ ] Provide a way to statically compile away the need for an executable GraphQL schema. Likely leveraging the work the Relay team has done to offer a Rust based framework for GraphQL manipulations. (Build-time flavour #2.)
- [ ] Provide a way to statically compile away runtime overhead for components that do not have normalized store needs. (Build-time flavour #3.)
- [ ] Provide an optimized runtime flavour that provides features requiring a normalized store. (Runtime flavour #3 & build-time flavour #4.)