Skip to content

GraphQL 'create' mutation fields become null for resource names with certain suffixes when name_converter is SnakeCaseToCamelCaseNameConverter #7390

@LuukOriginal

Description

@LuukOriginal

API Platform version(s) affected: 4.1.23

Description
When using SnakeCaseToCamelCaseNameConverter (the default), GraphQL 'create' mutations for certain resources (as far as I noticed mainly if you have a model named like "TestModel" returns null for all fields (except fields like __typename or id) in the response payload.

For example:

  • A simple resource named Test works as expected.
  • A similar resource named TestItem (or other multi-word names) is creates the entry correctly in the database, but the GraphQL createTestItem mutation response contains only the id and __typename. All other scalar fields are null.

The database entry is correct and a subsequent get query for the same resource works fine. The issue is only with the mutation return data.

How to reproduce

  1. Define two simple models/resources:
#[ApiResource(
    graphQlOperations: [new Mutation(name: 'create')]
)]
class Test extends Model
{
    protected $fillable = ['name'];
}

#[ApiResource(
    graphQlOperations: [new Mutation(name: 'create')]
)]
class TestItem extends Model
{
    protected $fillable = ['name'];
}
  1. Use the default config:
// config/api-platform.php
return [
    'name_converter' => Symfony\Component\Serializer\NameConverter\SnakeCaseToCamelCaseNameConverter::class,
];
  1. Run both mutations:

Successful:

mutation CREATE_TEST($input: createTestInput!) {
  createTest(input: $input) {
    test {
      id
      name
    }
  }
}

Unsuccessful:

mutation CREATE_TEST_ITEM($input: createTestItemInput!) {
  createTestItem(input: $input) {
    testItem {
      id
      name
    }
  }
}

Result:
For Test:

  • DB contains entry
  • All fields including name are specified correctly

For TestItem:

  • DB contains entry
  • All fields are null except id and __typename

If you change name_converter to null in api-platform.php, the response works as expected.

Possible Solution
It seems that the bug is caused by the SnakeCaseToCamelCaseNameConverter.
For resources with multi-word names (e.g. TestItem, TaskStatus), the generated GraphQL mutation response cannot map non-ID fields correctly.

Possible fixes:

  • Ensure the name converter is applied only to attributes/properties.
  • As a temporary workaround, setting 'name_converter' => null in config/api-platform.php fixes the issue, but is not always desirable .

Additional Context

  • Logs confirm the model has correct attributes after creation (name is persisted).
    I used this code for that within a broken model:
protected static function booted()
  {
      parent::booted();

      static::created(function ($model) {
          info('TaskStatus::created attributes: ' . json_encode($model->getAttributes()));
          info('TaskStatus::created toArray: ' . json_encode($model->toArray()));
          info('TaskStatus::created class: ' . get_class($model));
      });
  }
  • Queries for the resource work fine.
  • Environment: Laravel 12.28.1, PHP 8.4.5.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions