简体   繁体   中英

Symfony ApiPlatform GraphQl mutation fails when array of IRI is sent

Working with translations in a Symfony 5 + ApiPlatform v2.6 using GraphQl mutation with Angular 11 client (Apollo) I'm presenting the following workflow:

  1. Need to save the RecipeStepsTranslation entities to get the IRI
  2. Need to save then the RecipeStepEntity

All works fine when executing step 1, get the IRIs with a Promise.all() and pass it as array(which is the requested parameter for the GraphQl mutation).

Here is the mutation receiving some required parameter and the array of IRIs (the translations created previously). Notice that there is no error or exception raised on format, misspelling, or parameter names/types.

mutation createRecipeSteps($cookOrder: Int!, $translations: [String]) {
  createRecipeSteps(input: {cookOrder: $cookOrder, translations: $translations}) {
    recipeSteps {
      id
    }
  }
}

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

After send the mutation I receive the following Exception:

{
  "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
  }
}

As suggested I tried to change the keys for the locale representation(es|en) with an object but I got the same Exception.

If I'm passing an array of Strings as requested why is giving me this error. Thanks in advance!

I'm just guessing from the fact that you dealing with translations and the error, that the locale string should be the array key, the first key in your example would be int 0 where it throws the error.

So in php it is probably expecting something like this associative array of strings:

[
  "en" => "/api/recipe_steps_translations/1863",
  "es" => "/api/recipe_steps_translations/1864",
  "fr" => "/api/recipe_steps_translations/1865"
]

Defining that data in js would look like this:

let translations = {
  en: "/api/recipe_steps_translations/1863",
  es: "/api/recipe_steps_translations/1864",
  fr: "/api/recipe_steps_translations/1865"
}

And the JSON representation would be:

JSON.stringify(translations)
// or
"{\"en\":\"/api/recipe_steps_translations/1863\",\"es\":\"/api/recipe_steps_translations/1864\",\"fr\":\"/api/recipe_steps_translations/1865\"}"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM