-
Notifications
You must be signed in to change notification settings - Fork 61
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Research: DataObject subclass/extension in queries and mutation #11
Comments
Sam recommended that we don't use types for subclasses, and rather replicate the He further suggested to look into creating GraphQL queries dynamically based on form schema fields, and avoid querying all fields even if they're not required. Ingo has concerns on the practicality of this approach because Apollo expects queries to be registered as a Higher Order Component on component definition time, not at runtime within the component itself. |
More observations:
|
I've opened an issue on |
I've added an Option 3 "Fragment Registry" (#13) |
Research concluded in preferring Option 3 "Fragment Registry" (#13). This assumes we don't need access to all fields on the client (which would necessitate Option 1 or 2). Form submissions are handling generic types (not specific to models), hence can add fields dynamically (see #10). It's unclear how types will work with a React-based GridField, which needs to operate with different types on the same JavaScript source. It'll likely be a similiar solution to form submissions, where generic types expose |
Introduction
GraphQL requires a query to contain every field a view component could use, usually at "compile time". Apollo does this through the graphql-tag helper. There is no wildcard for fields, explicit field querying is built into the specification.
In SilverStripe, a form can display data from arbitrary fields based on your own project's
DataObject
subclass structure, as well asDataExtension
on existing models. This somewhat conflicts with GraphQL's assumptions about the static nature of views and their data requirements.In order to retain SilverStripe's ability to influence the view through PHP only, we need a way for GraphQL to include fields from
DataObject
subclasses andDataExtension
in queries and mutations, without requiring recompilation of the JS bundle.This will also become an issue when using GraphQL as a general purpose SilverStripe Content API: You'd need to construct queries based on introspection in order to return all available data for a particular
DataObject
structure. Since this structure differs between projects, there's no predefined query to query all fields.Story Candidates
File
and subclasses are one single type)gql
AST from JSON structure for particular queries and mutations (ingest the introspection JSON)Option 1: Use a "fields" array on types
This negates most of the advantages of using GraphQL in the first place (strong typing), since we're only creating types for the field metadata (
name
andvalue
), not the actual type signature.Return:
Option 2: Compose GraphQL queries by introspection
GraphQL supports introspection of types and queries, which allows us to identify all available queries upfront. Queries can use interfaces for a returned type, but we can't infer types from these (determined at runtime through GraphQL resolvers). We need to include all fields from the respective types, potentially as reuseable fragments.
GraphQL in Apollo is parsed via the
gql
template literal tag and the graphql-tag library.Option 3: Fragment Registry
If we exclude strongly typed form state and submissions, we're left with GraphQL view components which know their fields upfront since they're using them directly as props (for example
<Gallery>
knows it'll need atitle
prop, but has no built-in use for other fields which might be added through aDataExtension
). This means new fields in GraphQL queries will always coincide with new view components using them. This can be solved through a "fragment registry" which adds fragments ("containers" for new fields) to named queries: #13Notes
SiteTree
subclasses (e.g.RedirectorPage
, orMyCustomPage
), and save them back to their respective database columnsExample Query
This is a query to read file data (from AssetAdmin.js).
Example Introspection query
Returns
https://gist.github.com/chillu/d13cc32771223a15d7b995e581704f54
The text was updated successfully, but these errors were encountered: