Proposal: Breaking GraphiQL APIs & New APIs 💥 -> 🚀
See original GitHub issueNOTE: most important detail is what we are keeping, and that is almost all of the GraphiQL props
1. GraphQL.state
(e.g. GraphiQL.state.query
) is being accessed directly, and is advertised somewhat as a public interface in the Readme and has been for some time. However, our move to context means that providers will contain state. Also there will be multiple queries with multple tabs! Also if I’m not mistaken it’s not really reccomended to access Component state directly like that?
replacement proposal:
const { query } = GraphiQL.state
becomes
const { operation } = useOperationContext({ tabId: 0 })
and this one which will require the parent workspace context to work (i.e. a tab plugin, etc), and already know which is the active tab by default from parent workspace context.
const { operation } = useOperationContext()
also for non-hooks class component style, they can still in a tab plugin use:
<OperationContext.Consumer>{({ operation }) => ()}</OperationContext.Consumer>
2. GraphiQL.methods()
There are also Component methods that are used to access values, submit queries programatically, and for many other purposes in the wild.
- `onEditQuery’
These also will move to context provider, possibly just dispatch actions with types that pass args mapped to some of the same and some new method names.
then you can readily dispatch actions via a similar interface:
const = { operation, setOperation } = useOperationContext({ tabId: 'current' })
return (
<textarea onChange={e => setOperation(e.target.value)}></textarea>
)
also in a panel/tab context:
<OperationContext.Consumer>{({ setOperation }) => ()}</OperationContext.Consumer>
a better approach with useGraphiQLReducers()
import { useGraphiQLReducers, Actions } from 'graphiql'
function ASTReducer(action, state) {
switch(action.type) {
case [Actions.onOperationChange]: {
state.operationAST = parse(state.operations.get(action.tabId));
return state
}
default {
return state
}
}
}
useGraphiQLReducers({
init: () => { operations: new Map(['mutation SendMsg{ send(msg:"hello!"){response} }']),
reducers: [ASTReducer]
})
hopefully we can figure out how to provide side effects for actions in useGraphiQLReducers
as well?
the GraphiQL.methods() interfaces are also accessible outside of a bundler for react JSX (Parcel, Webpack, Rollup, etc). this new proposal however would require one of these bundlers to achieve these kinds of capabilities. You can also use React.createElement
directly with the contexts we will export to avoid that, but that might grow cumbersome
3: GraphiQL.Logo
and friends
These are a cute interface but they will be deprecated soon for new patterns for defining your own layouts for the workspace and operation editor panes layout per tab, and replacing components programatically in ways that will be provided by plugins.
Also, @walaura is plugging away at a new theme provider and baseline theme and components that we will begin to adopt into our component tree and you will be able to override the theme defaults and style at the props level, again a prototypical interface over plugins.
Summary
All of these interface will need to be dropped so we can make way for the first proto-plugin features, which will be defining custom components that inherit workspace/operation tab context that you can pass from the GraphiQL component, and will be rendered either in the left or right panes, and will optionally have an icon in the icon bar and labels and such.
These will expose the above mentioned capabilities, and none of this requires a plugin layer yet, and these interfaces should hopefully be close to what the plugin interfaces will be for RC. hooray react for making it so easy to create extensible components!
The way we pass these early “plugins” to GraphiQL will be at the props level, maybe in a plugins
array. Eventually you’ll be able to use graphql config to provide predefined plugins with their own settings overrides in graphql “presets” that you build with webpack, and eventually hopefuly the ability to search, select and install/uninstall/disable etc plugins over the wire! not as far off as it might seem!
Notes:
- I’m tempted to start renaming “query” to operation, unless it refers to a query operation, in the codebase. i think i will start discussion issues for all these topics
- the above examples are just psuedocode and still has yet to be proofed, just meant to get the conversation started on what it could look like. working group calls very soon!
Related Issues:
Issue Analytics
- State:
- Created 4 years ago
- Reactions:7
- Comments:6 (4 by maintainers)
Top GitHub Comments
@acao can you give me some starter point regarding #828. As you mentioned we can do it using
reducer
. I already read the conversation regarding plugin in #829 and really excited about this feature.Feels fine to break these considering the extra opportunities the plugin system offers instead of these