-
Notifications
You must be signed in to change notification settings - Fork 111
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 API #237
Comments
Doing some thinking about the plugin API. (This is pretty rough, thoughts are very welcome though.) Next thing to do is probably to make a POC implementation of this, and try writing some plugins. As pre-work it may be useful to refactor directive-parsing to happen along with query-parsing, and we can probably get #151 as a part of that. At some point we'll also need to figure out the config, but that seems comparatively easy (and is safer to do in a crappy way (copy from golangci-lint) and then improve later if needed). query rewritingA thing we can definitely expose is query rewriting. Some plugins would want that between parsing and validation, others might want it post-validation. Something like: type PluginInput struct {
Config *generate.Config
Schema *ast.Schema
QueryDocuments *[]*ast.QueryDocument // modify in place(?)
}
type Plugin interface {
RewriteBeforeValidation(*PluginInput) error
RewriteAfterValidation(*PluginInput) error
} That lets you do # @entityquery(by: "id")
fragment MyQueryUser on User { ... }
# compiles to add
query MyQuery(
$representations: [_Any!]!,
) {
_entities(representations: $representations) { ...MyQueryUser }
} but then you also want to do something about that genqlient directivesAn obvious thing there is you can add a genqlient directive. The exact API for this is not totally obvious, since those aren't really in the AST, but we can come up with something. Then you can add API here could look something like type GenqlientDirective struct { /* existing, newly exported */ }
type Plugin interface {
// or: add the return to the two rewrite methods above
// or: actually this goes in the input so you can preprocess directives too
AddDirectives(*PluginInput) ([]*GenqlientDirective, error)
} It's less clear to me exactly what we want for hasura/dgraph, but "add a bunch of genqlient directives automatically" may be mostly sufficient. (Half of the problem there is just that the defaults don't work well for them, which can be solved via configuration, but perhaps more flexibly by a plugin.) An implementation trouble is that directives are parsed lazily, but that's surely fixable. (And it might improve the code to do so, the directive-checking code gets pretty messy.) go typesFor adding net-new Go types like Then some of the requests want changes to genqlient-generated structs. We could expose the stuff in In sum that looks something like: // plugins may modify any fields in place
type PluginContext struct {
Config *generate.Config
Schema *ast.Schema
QueryDocuments *[]*ast.QueryDocument
Directives *[]*GenqlientDirective
ExtraGoTypes map[string]string // (nil, fill in if you need it)
}
type Plugin interface {
RewriteBeforeValidation(*PluginContext) error
RewriteAfterValidation(*PluginContext) error
} and I think at least in principle that can do all the potential examples except |
Another question for a plugin API is: how much can we rewrite from the core into plugins? (If we did this they'd of course be builtin plugins, so you don't have to link them in yourself or anything, it's more a test of the abstraction than to get functionality out of repo.) Scanning through the "non-core" settings in
|
It seems like one day, maybe soon, we'll find value in a plugin API, so users can hook into codegen in ways that we can't anticipate. This issue is to collect both examples of plugins we might want, and ideas for how to do them.
A few things to think about:
Issues that might be best done via a plugin (please suggest any other use cases you come across):
The text was updated successfully, but these errors were encountered: