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

Generic data producer directive #1238

Open
chindris opened this issue Nov 3, 2022 · 2 comments
Open

Generic data producer directive #1238

chindris opened this issue Nov 3, 2022 · 2 comments

Comments

@chindris
Copy link
Contributor

chindris commented Nov 3, 2022

After we have the chain of directives in #1170 , we could also implement a directive to invoke an arbitrary data producer. Then we could basically replace a lot of code in the custom schema implementation that would just use $builder->compose() to chain simple data producers.

The new directive would have two parameters:

  • name: the name of the data producer plugin
  • args: a Map of arguments to feed the data producer plugin. Depending on the value of each map entry, we would call a specific builder resolver, for example:
  1. if the value of the map entry is 'fromParent' then we map the key of the map entry to $builder->fromParent().
  2. if the value of the map entry matches 'fromArgument:argument_name', the we map the key of the map entry to $builder->fromArgument(argument_name)
  3. we can add other cases, like fromContext, fromPath, etc...
  4. if none of the above matches, then we just map the key of the map entry to $builder->fromValue(value_of_the_map_entry)

A possible example:
type MyType {
myField(someArg: String): String @dataProducer(name: 'some_data_producer_id', args:{entity: 'fromParent', input: 'fromArgument:someArg', bundle: 'entity:node'})
}

In the directive implementation, we'd have the result:
$builder->produce('some_data_producer_id')
->map('entity', $builder->fromParent())
->map('input', $builder->fromArgument('someArg'))
->map('bundle', $builder->fromValue('entity:node')

@pmelab
Copy link
Contributor

pmelab commented Dec 21, 2022

fromParent and fromArgument already exist as $ and $myArgument:

## Argument handling
Directives can use the `ArgumentTrait` to apply dynamic arguments. If the
directive argument equals `$`, the current value will be passed as the argument
value. If its `$`, followed by any characters, these characters will be used as
a key to retrieve the value from the current query arguments.
Arguments that implement this behaviour are marked to be (dynamic).
```graphql
type Query {
static: Post @loadEntity(type: "node", id: "1")
parent: Post @value(json: "1") @loadEntity(type: "node", id: "$")
argument(id: String!): Post @loadEntity(type: "node", id: "$id")
}
```

The problem with a generic directive is that we don't have typing for args. It would have to be a very verbose generic mapping type.

type MyType {
    myField(someArg: String): String @dataProducer(name: 'some_data_producer_id', args:[
      {key: "entity", value: "$"},
      {key: "input", value: "$someArg"}, 
      {key: "bundle", value: "entity:node"}
    ])
}

This would work, but there would be no coding assistance for argument names.

Another idea: We could derive directives from resolver plugins. Then it could look like this:

type MyType {
    myField(someArg: String): String @produce__some_data_producer_id(name: 'some_data_producer_id', args:{
      entity: "$",
      input: "$someArg",
      bundle: "entity:node"
    })
}

This would retain autocomplete support on everything.

@pmelab
Copy link
Contributor

pmelab commented Dec 21, 2022

And sorry for seeing this almost two months later 🤯

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants