Feature request: Allow developer to set custom GraphQL operation name
Description
At the moment, it's not possible to overrule GraphQL operation names as is possible on REST operations. In my case, I would like to do that because pluralization of my Dutch ApiResource ("Land") results in an incorrect operation name ("Lands" instead of "Landen"). In the current situation, there is no way to 'skip' pluralization done in: https://github.com/api-platform/core/blob/92e82aafba809472f45199f1e67e60c0b4f15d19/src/GraphQl/Type/FieldsBuilder.php#L125
I think implementing of a way to force the operation 'name' is not very difficult (see below) and I can make a PR for it, but am not sure about the property name to use for this. Using uriTemplate seems logical in terms of consistency between REST and GraphQL, but in GraphQL queries are not URI, so that property name is not very self-explaining.
Another solution I thought of was allowing developers to disable pluralization and use 'shortName' on operation level to set the operation name, but that also creates clones of the return type, so I think that's not the way to go.
The same feature should be implemented in mutations and operations, to make it consistent.
Example
#[ApiResource(
shortName: 'Land',
operations: [
new Get(uriTemplate: '/landen/{id}.{_format}'),
new GetCollection(uriTemplate: '/landen.{_format}'),
],
graphQlOperations: [
new Query(),
new QueryCollection(uriTemplate: 'landen'),
]
)]
#[ORM\Entity(LandRepository::class)]
#[ORM\Table('main_land')]
class Land
{
public function getCollectionQueryFields(string $resourceClass, Operation $operation, array $configuration): array
{
if (null === $operation->getUriTemplate()) {
$fieldName = lcfirst('collection_query' === $operation->getName() ? $operation->getShortName() : $operation->getName().$operation->getShortName());
$fieldName = Inflector::pluralize($fieldName);
} else {
$fieldName = $operation->getUriTemplate();
}
if ($fieldConfiguration = $this->getResourceFieldConfiguration(null, $operation->getDescription(), $operation->getDeprecationReason(), new Type(Type::BUILTIN_TYPE_OBJECT, false, null, true, null, new Type(Type::BUILTIN_TYPE_OBJECT, false, $resourceClass)), $resourceClass, false, $operation)) {
$args = $this->resolveResourceArgs($configuration['args'] ?? [], $operation);
$configuration['args'] = $args ?: $configuration['args'] ?? $fieldConfiguration['args'];
return [$fieldName => array_merge($fieldConfiguration, $configuration)];
}
return [];
}