Introductions Agenda Recap Update on next spec release
- In last meeting, SDL was the last blocker for next version of the spec
- Identified compelling blocker: default values and null
- Question: about timeframe between releases
- This release is special, a lot of new releases
- Interconnected parts to this release
- Tradeoff between scrutiny on individual proposals – where changes affect the dynamics between parts – to ensure integration quality
- Prioritize the core stability of GraphQL, assure the community
- Changing the behavior of existing use cases in GraphQL should proceed with caution especially considering query execution and results
- Is semver the right fit?
- Gold standard is no breaking changes
- Inspiration from TC39 to reference year and/or month – annual cadence
- Most of the work for cutting involves documenting changes and spec changes
- Boundaries for different aspects: execution, validation, SDL, etc
- Issues of compatibility: whole or unit based
- Supporting one functionality but not the rest does not exclude a framework or library from being labeled as true "GraphQL"
- How to track and identify pull requests for next cut/release?
- Identifying stage of proposal lifecycle
- Preference for high scrutiny on what makes next release, limited to security issues and high impact changes
- Including next-generation proposals
- Browser includes stage-2 and stage-3 proposals in release before they complete. GraphQL should be no different
- Let maintainers decide whether to put proposals behind a flag.
- Mike's Proposal: interface hierarchy, an interface implements another interface
- Example Use Case: Relay Cursor Specification
- Interfaces to drive a connection wouldn't work if you wanted a connection that returns a particular interface
- More than one layer of wrapping allows no way to declare an interface and subset of interface selection
- Allow an interface to declare that it implements another interface
- All concrete types must declare an interface of what they implement
- Change in metadata only
- RFC is prepared, implemented in GraphQL JS
- Not much to change in Relay
- Insights in to change costs?
- In Sangria, when defining object types or interfaces you can implement other interfaces. Not exposed to introspection
- Does the proposal/RFC have momentum?
- Concern of change cost, and value added
- Clarify what use cases are exposed – brand new that couldn't be expressed before, or making existing use cases less awkward
- Need to identify other use cases and edge cases
- Interface validation is already in PR
- From client perspective, consuming JSON output and introspection query requires spec change
- Change costs for code generation and type generation based on schema
- Potential issue:
- If an object implements NamedNode but not Node, does that throw an error?
- In RFC, it fails validation on compilation
- If interface extends another interface, are the fields required to be defined as its own property?
- Yes
- If an object implements NamedNode but not Node, does that throw an error?
- Example Use Case: Relay Cursor Specification
- Null default values
- Issue occurs in both GraphQL JS and confirmed by Oleg
- Before null became a literal value in language, absence and null were same thing
- Type that is nullable that had a default value, result of that variable could be safely passed to an argument that requires non-null version
- Ex: Query loads by ID, default ID is nullable default object
- Passing it through to something that needs ID is non-issue until null literal was introduced
- Default value could be null and passed to non-null
- Potential attack vector for sending null to non-nullable
- Any value, even passed with null literal, is possible to pass to non-nullable
- Non-nullable needs guarantee to not have null at runtime
- Type that is nullable that had a default value, result of that variable could be safely passed to an argument that requires non-null version
- Proposal:
- If default value is null literal, validator should catch passing to non-nullable
- Passing a runtime null value – change resolution of actual runtime value (null) to use the default value instead
- No argument passed vs null
- Changes execution behavior
- Counterproposal:
- Don't change execution behavior
- Change validation rules – if variable has default value, throw error if it's a non-nullable type. Have to declare it as also non-nullable
- Can still add default value, cannot be null
- Can't pass runtime null
- All existing queries would be invalid, shipped clients with runtime assembly and live validation will break.
- Discussion:
- Observation: least used features is default values
- Goal should be a clear mental model
- If using counterproposal, some awkward compatibility mode
- Rather than checking for null, add an additional null check
- Prefer high stability, both are potentially breaking, which breakage is more costly?
- More knowledge around impact of queries vs fields
- Need to make suggestions for three audiences:
- Maintainers - easy
- Administrators – manageable
- Query writers – high impact
- Using a feature flag
- Disable particular validations if they want to stay compatible
- Another RFC: if union inputs were allowed nullable or non-nullable. Any nulls would use current behavior. Anything non-nullable would use the next behavior.
- Actionable items:
- Sizing impact
- OpenCrud
- Goal is that community can specify how you would expose a MySQL database or Cassandra database through a GraphQL API
- Relational databases
- Graph databases
- Document databased
- How to create a spec to expose large data?
- Per category of databases, with explicit purpose for each category
- Goal is that community can specify how you would expose a MySQL database or Cassandra database through a GraphQL API
- For top level directives:
- Node package GraphQL imports, why are we commenting it out?
- Using directives instead, but more cumbersome to use
- Few proposals for addressing syntactical fatigue
- Following up – help wanted
- High impact on schema stitching
- Already have top level directive in some sense with directive on schema itself
- Concatenating files together comes with pitfalls, hierarchy issues
- Node package GraphQL imports, why are we commenting it out?
- GraphQL JS Documentation
- Currently is a series of markdown files in the org site
- Preference to be language agnostic, platform aware
- Documentation rot as GraphQL JS has evolved
- Contrast to high visibility of documentation in the code itself
- High value, open to ecosystem
- High impact in pointing from language-specific documentation to the org/platform documentation.
- Suggestion: have a section for all languages and resources
- Reflection from Siddharth @ Glassdoor:
- Concepts can be overwhelming, sometimes requiring different degrees of experience
- Having access to end-to-end examples is important
- Actionable items:
- Shifting responsibility of maintainers to link to better resources
- Separation of GraphQL JS from Platform websites
- Stability for linking to stable and draft specs, resources
- Helping ecosystem achieve parity
- Misunderstanding that node/JS is the only way to run in production
- Possible influence of tight coupling of JS/Platform documentation
- Expect same behaviors between languages
- Maintainer cadence – creating a chat to bring maintainers together
- Actionable items
- Central repository for each spec feature
- Able to test against acceptance tests
- GraphQL CATS:
- Application to multiple languages using drivers
- Idea: requiring tests to add to spec, etc
- Write schema and query, but what about resolvers?
- Directives in Java
- Leveraging the strength of languages resulting in different APIs
- JavaScript and other functional languages have primitive resolvers
- Counterexample: Java annotations
- Need to add more drivers