Skip to content
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

Plugin: query manipulation pipeline #771

Open
batanun opened this issue Feb 27, 2019 · 6 comments
Open

Plugin: query manipulation pipeline #771

batanun opened this issue Feb 27, 2019 · 6 comments
Labels
graphiql potential plugin A potential plugin idea for later versions of GraphiQL

Comments

@batanun
Copy link

batanun commented Feb 27, 2019

Proposal

Quick summary

It would be a really useful feature to be able to programatically modify the query before execution.

Description of the problem at hand

In our case, we use the GraphiQL editor as part of a bigger system, a CMS. And this CMS provides a way to do some modifications to the query, in a plugin style (the plugin is handled the query, and can modify it any way it wants). This works fine when using the system in the normal way, ie triggering graphql using an API call, and getting the json response. But it doesn't work as expected when we use the GraphiQL editor. Because the CMS hands over the already modified query (originally from a file on disk) to the editor. So the original query is never displayed.

The fact that the editor is displaying the already modified query is problematic in two ways:

  1. One of the CMS plugins might implement some import like feature, that replaces a single line in the original query with much more complex sub-query, this makes the query in the editor more difficult to read
  2. If the query is loaded from a permament storage, and then saved using GraphiQL, then the original query is overwritten with the modified version, even if the user didn't modify the displayed query in any way

And since GraphiQL handles the GraphQL execution itself, it is not possible to simply hand it the original query, because GraphiQL doesn't know about the CMS plugins and how they would modify the query.

Description why this would benefit other users of GraphiQL

Our use case might not be the common one, but the general idea of being able to modify the GraphQL query with some custom code, while still being able to use GraphiQL to edit the original query, is probably quite universal.

Current workaround

We don't really have a workaround for this. The GraphiQL editor is an essential tool for administrators of the CMS, including modifying and saving queries using it. So we currently can't use the "modify query" plugin feature of the CMS.

Possible solution

Currently GraphiQL takes a fetcher to get the graphQL query, and uses the resulting query both in the editor and for execution. This approach could be extended, giving the option to also provide a transformer, that takes as input the query from the editor panel, and returns the transformed query. GraphiQL would then always display the result of the fetcher in the editor panel, but the query used for the execution would be the one returned from the transformer. If no transformer is defined, then the query from the fetcher is used (ie just as it works today).

Potential problems, and possible ways to handle them

If the transformed query results in a totally different structure compared to the original query, the user might get confused. The same confusion could arrise if the transformed query results in an error that doesn't easily correspond to a line in the original query, and it would make troubleshooting more difficult. Neither of these problems are caused of GraphiQL, naturally, but it would still be good if GraphiQL could help the user deal with this.
The simple solution to this could be to just display some kind of warning to the user, informing them of the fact that the query was modified before execution, and that any surprices in the result could be because of that. A more elegant solution could be to show an optional third panel that shows the transformed query, or a button that switches between the original query and the transformed one (possibly in read only mode).

@imolorhe
Copy link
Contributor

@acao Potentially solved with the plugin system, can be created as a custom plugin by the CMS developers.

@benjie benjie added the potential plugin A potential plugin idea for later versions of GraphiQL label Aug 12, 2019
@acao
Copy link
Member

acao commented Aug 12, 2019

@batanun this should be possible with a custom fetcher, supplied via props

@benjie benjie changed the title Proposal: Make it possible to programatically modify query before execution Plugin: query manipulation pipeline Dec 10, 2019
@benjie
Copy link
Member

benjie commented Dec 10, 2019

I've renamed this issue to "query manipulation pipeline" because I think this is a more general way of handling this problem and also #612.

I think this is beyond a fetcher concern because we'd also want various other plugins to know about the "cooked" query as well as the "raw" query; for example a lint plugin would be upset about GatsbyImageSharpFixed being referenced but not defined in the raw query; but in the cooked query it'd be happy. We might need to figure out how to map back and forwards so we can apply "cooked" lint errors to the "raw" query; that may require source map support.

@benjie
Copy link
Member

benjie commented Dec 10, 2019

(But currently it can 100% be implemented with a fetcher.)

@acao
Copy link
Member

acao commented Dec 10, 2019

for example a lint plugin would be upset about GatsbyImageSharpFixed being referenced but not defined in the raw query;

this is why im working with gatsby folks to ensure we add fragments at the LSP level (already supported by the lsp) so that the linter honors the hidden fragments automatically. no sense in hacking this entirely at the GraphiQL level when we have a whole LSP we can customize with!

@benjie
Copy link
Member

benjie commented Dec 10, 2019

For this particular issue, so long as we can get both the "raw" and "cooked" versions of the query so we can run tools like eslint-plugin-graphql against them, I don't think it matters greatly which part of the system actually implements the pipeline. It probably makes sense to handle it as an AST (converting back to string would be an unnecessary overhead IMO), so doing it in the LSP would probably be most sensible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
graphiql potential plugin A potential plugin idea for later versions of GraphiQL
Projects
Status: Todo
Development

No branches or pull requests

4 participants