Locastic / ApiPlatformTranslationBundle

Translation bundle for ApiPlatform based on Sylius translation
MIT License
85 stars 28 forks source link

Translations create not working as expected when GraphQl is used #40

Open jmoralespestana opened 3 years ago

jmoralespestana commented 3 years ago

Thanks for your great work in advance!

The translations are working very well.

But when GraphQl is used there is an issue related to the Translation entity serialization proccess.

Entities related

Workflow

  1. Use createRecipeStepsTranslation mutation returning the IRI [success]
  2. Create an array of string to pass to next mutation [success]
  3. Use the createRecipeSteps mutation [fail]

The request made is described as follow:

// the parameters are the same suggested by GraphQl docs
mutation createRecipeSteps($cookOrder: Int!, $translations: [String]) {
  createRecipeSteps(input: {cookOrder: $cookOrder, translations: $translations}) {
    recipeSteps {
      id
    }
  }
}

// set of variables
{
  "translations": [
    "/api/recipe_steps_translations/1863",
    "/api/recipe_steps_translations/1864",
    "/api/recipe_steps_translations/1865"
  ],
  "cookOrder": 0
}

After send the query the next error is raised

{
  "errors": [
    {
      "debugMessage": "The type of the key \"0\" must be \"string\", \"integer\" given.",
      "message": "Internal server error",
      "extensions": {
        "category": "internal"
      },
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "createRecipeSteps"
      ],
      "trace": [
        {
          "file": "W:\\projects\\apps\\sample-api\\vendor\\api-platform\\core\\src\\Serializer\\AbstractItemNormalizer.php",
          "line": 737,
          "call": "ApiPlatform\\Core\\Serializer\\AbstractItemNormalizer::denormalizeCollection('translations', instance of ApiPlatform\\Core\\Metadata\\Property\\PropertyMetadata, instance of Symfony\\Component\\PropertyInfo\\Type, 'App\\Entity\\RecipeStepsTranslation', array(3), 'graphql', array(8))"
        },
        {
          "file": "W:\\projects\\apps\\sample-api\\vendor\\api-platform\\core\\src\\Serializer\\AbstractItemNormalizer.php",
          "line": 403,
          "call": "ApiPlatform\\Core\\Serializer\\AbstractItemNormalizer::createAttributeValue('translations', array(3), 'graphql', array(8))"
        },
        {
          "file": "W:\\projects\\apps\\sample-api\\vendor\\api-platform\\core\\src\\GraphQl\\Serializer\\ItemNormalizer.php",
          "line": 128,
          "call": "ApiPlatform\\Core\\Serializer\\AbstractItemNormalizer::setAttributeValue(instance of App\\Entity\\RecipeSteps, 'translations', array(3), 'graphql', array(8))"
        },
        {
          "file": "W:\\projects\\apps\\sample-api\\vendor\\symfony\\serializer\\Normalizer\\AbstractObjectNormalizer.php",
          "line": 336,
          "call": "ApiPlatform\\Core\\GraphQl\\Serializer\\ItemNormalizer::setAttributeValue(instance of App\\Entity\\RecipeSteps, 'translations', array(3), 'graphql', array(8))"
        },
        {
          "file": "W:\\projects\\apps\\sample-api\\vendor\\api-platform\\core\\src\\Serializer\\AbstractItemNormalizer.php",
          "line": 250,
          "call": "Symfony\\Component\\Serializer\\Normalizer\\AbstractObjectNormalizer::denormalize(array(2), 'App\\Entity\\RecipeSteps', 'graphql', array(8))"
        },
        {
          "file": "W:\\projects\\apps\\sample-api\\vendor\\api-platform\\core\\src\\Serializer\\ItemNormalizer.php",
          "line": 70,
          "call": "ApiPlatform\\Core\\Serializer\\AbstractItemNormalizer::denormalize(array(2), 'App\\Entity\\RecipeSteps', 'graphql', array(7))"
        },
        {
          "file": "W:\\projects\\apps\\sample-api\\vendor\\symfony\\serializer\\Serializer.php",
          "line": 208,
          "call": "ApiPlatform\\Core\\Serializer\\ItemNormalizer::denormalize(array(2), 'App\\Entity\\RecipeSteps', 'graphql', array(6))"
        },
        {
          "file": "W:\\projects\\apps\\sample-api\\vendor\\api-platform\\core\\src\\GraphQl\\Resolver\\Stage\\DeserializeStage.php",
          "line": 57,
          "call": "Symfony\\Component\\Serializer\\Serializer::denormalize(array(2), 'App\\Entity\\RecipeSteps', 'graphql', array(6))"
        },
        {
          "file": "W:\\projects\\apps\\sample-api\\vendor\\api-platform\\core\\src\\GraphQl\\Resolver\\Factory\\ItemMutationResolverFactory.php",
          "line": 98,
          "call": "ApiPlatform\\Core\\GraphQl\\Resolver\\Stage\\DeserializeStage::__invoke(null, 'App\\Entity\\RecipeSteps', 'create', array(6))"
        },
        {
          "file": "W:\\projects\\apps\\sample-api\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
          "line": 624,
          "call": "ApiPlatform\\Core\\GraphQl\\Resolver\\Factory\\ItemMutationResolverFactory::ApiPlatform\\Core\\GraphQl\\Resolver\\Factory\\{closure}(null, array(1), null, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
        },
        {
          "file": "W:\\projects\\apps\\sample-api\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
          "line": 550,
          "call": "GraphQL\\Executor\\ReferenceExecutor::resolveFieldValueOrError(instance of GraphQL\\Type\\Definition\\FieldDefinition, instance of GraphQL\\Language\\AST\\FieldNode, instance of Closure, null, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
        },
        {
          "file": "W:\\projects\\apps\\sample-api\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
          "line": 474,
          "call": "GraphQL\\Executor\\ReferenceExecutor::resolveField(GraphQLType: Mutation, null, instance of ArrayObject(1), array(1))"
        },
        {
          "file": "W:\\projects\\apps\\sample-api\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
          "line": 858,
          "call": "GraphQL\\Executor\\ReferenceExecutor::GraphQL\\Executor\\{closure}(array(0), 'createRecipeSteps')"
        },
        {
          "call": "GraphQL\\Executor\\ReferenceExecutor::GraphQL\\Executor\\{closure}(array(0), 'createRecipeSteps')"
        },
        {
          "file": "W:\\projects\\apps\\sample-api\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
          "line": 860,
          "function": "array_reduce(array(1), instance of Closure, array(0))"
        },
        {
          "file": "W:\\projects\\apps\\sample-api\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
          "line": 490,
          "call": "GraphQL\\Executor\\ReferenceExecutor::promiseReduce(array(1), instance of Closure, array(0))"
        },
        {
          "file": "W:\\projects\\apps\\sample-api\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
          "line": 263,
          "call": "GraphQL\\Executor\\ReferenceExecutor::executeFieldsSerially(GraphQLType: Mutation, null, array(0), instance of ArrayObject(1))"
        },
        {
          "file": "W:\\projects\\apps\\sample-api\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
          "line": 215,
          "call": "GraphQL\\Executor\\ReferenceExecutor::executeOperation(instance of GraphQL\\Language\\AST\\OperationDefinitionNode, null)"
        },
        {
          "file": "W:\\projects\\apps\\sample-api\\vendor\\webonyx\\graphql-php\\src\\Executor\\Executor.php",
          "line": 156,
          "call": "GraphQL\\Executor\\ReferenceExecutor::doExecute()"
        },
        {
          "file": "W:\\projects\\apps\\sample-api\\vendor\\webonyx\\graphql-php\\src\\GraphQL.php",
          "line": 162,
          "call": "GraphQL\\Executor\\Executor::promiseToExecute(instance of GraphQL\\Executor\\Promise\\Adapter\\SyncPromiseAdapter, instance of GraphQL\\Type\\Schema, instance of GraphQL\\Language\\AST\\DocumentNode, null, null, array(2), 'createRecipeSteps', null)"
        },
        {
          "file": "W:\\projects\\apps\\sample-api\\vendor\\webonyx\\graphql-php\\src\\GraphQL.php",
          "line": 94,
          "call": "GraphQL\\GraphQL::promiseToExecute(instance of GraphQL\\Executor\\Promise\\Adapter\\SyncPromiseAdapter, instance of GraphQL\\Type\\Schema, 'mutation createRecipeSteps($cookOrder: Int!, $translations: [String]) {\n  createRecipeSteps(input: {cookOrder: $cookOrder, translations: $translations}) {\n    recipeSteps {\n      id\n    }\n  }\n}\n', null, null, array(2), 'createRecipeSteps', null, null)"
        },
        {
          "file": "W:\\projects\\apps\\sample-api\\vendor\\api-platform\\core\\src\\GraphQl\\Executor.php",
          "line": 34,
          "call": "GraphQL\\GraphQL::executeQuery(instance of GraphQL\\Type\\Schema, 'mutation createRecipeSteps($cookOrder: Int!, $translations: [String]) {\n  createRecipeSteps(input: {cookOrder: $cookOrder, translations: $translations}) {\n    recipeSteps {\n      id\n    }\n  }\n}\n', null, null, array(2), 'createRecipeSteps', null, null)"
        },
        {
          "file": "W:\\projects\\apps\\sample-api\\vendor\\api-platform\\core\\src\\GraphQl\\Action\\EntrypointAction.php",
          "line": 86,
          "call": "ApiPlatform\\Core\\GraphQl\\Executor::executeQuery(instance of GraphQL\\Type\\Schema, 'mutation createRecipeSteps($cookOrder: Int!, $translations: [String]) {\n  createRecipeSteps(input: {cookOrder: $cookOrder, translations: $translations}) {\n    recipeSteps {\n      id\n    }\n  }\n}\n', null, null, array(2), 'createRecipeSteps')"
        },
        {
          "file": "W:\\projects\\apps\\sample-api\\vendor\\symfony\\http-kernel\\HttpKernel.php",
          "line": 157,
          "call": "ApiPlatform\\Core\\GraphQl\\Action\\EntrypointAction::__invoke(instance of Symfony\\Component\\HttpFoundation\\Request)"
        },
        {
          "file": "W:\\projects\\apps\\sample-api\\vendor\\symfony\\http-kernel\\HttpKernel.php",
          "line": 79,
          "call": "Symfony\\Component\\HttpKernel\\HttpKernel::handleRaw(instance of Symfony\\Component\\HttpFoundation\\Request, 1)"
        },
        {
          "file": "W:\\projects\\apps\\sample-api\\vendor\\symfony\\http-kernel\\Kernel.php",
          "line": 195,
          "call": "Symfony\\Component\\HttpKernel\\HttpKernel::handle(instance of Symfony\\Component\\HttpFoundation\\Request, 1, true)"
        },
        {
          "file": "W:\\projects\\apps\\sample-api\\public\\index.php",
          "line": 20,
          "call": "Symfony\\Component\\HttpKernel\\Kernel::handle(instance of Symfony\\Component\\HttpFoundation\\Request)"
        }
      ]
    }
  ],
  "data": {
    "createRecipeSteps": null
  }
}

When I use another parameters as array of IRIs of previously saved objects this is not happening, only fails with translation.

Would it be posible the translations are not available to save this way when using GraphQl?

oachoor commented 3 years ago

@jmoralespestana did you manage to get this to work?