nilportugues / symfony-jsonapi

JSON API Transformer Bundle for Symfony 2 and Symfony 3
http://nilportugues.com
MIT License
115 stars 19 forks source link

Collection response + snake case / camelCase issue #17

Open guiguiboy opened 8 years ago

guiguiboy commented 8 years ago

Hello,

First of all, thanik you for your work. I am currently using your bundle for my REST API. I am currently facing an issue with 2 routes that exports the same kind of objects (user objects):

For the list route, I use the following mapping file :

mapping:
  class: \Doctrine\Common\Collections\ArrayCollection
  alias: Collection
  hide_properties: []
  urls:
    self: admin_get_users ## @Route name

In my controller, I retrieve a list of users which I output as you described in your doc. In the response, I have :

{
  "data": {
    "type": "collection",
    "id": "",
    "attributes": [],
    "relationships": {
      "elements": [
        {
          "data": {
            "type": "user",
            "id": "1"
          }
        },
        {
          "data": {
            "type": "user",
            "id": "2"
          }
        },
        {
          "data": {
            "type": "user",
            "id": "3"
          }
        }
      ]
    }
  },
  "included": [
    {
      "type": "user",
      "id": "1",
      "attributes": {
        "username": "gbu",
        "email": "gbu@example.com",
        "initials": null,
        "firstName": "....",
        "surnamePrefix": null,
        "surname": "....",
        "enabled": true,
        "locked": false,
        "lastLogin": null,
        "roles": [
          "ROLE_ADMIN",
          "ROLE_USER"
        ]
      }
    },
...

I was expecting to retrieve the user objects direcly in the "data" node but it's available in the "included" node. What configuration do I need to use to have such output ?

I also noticed another thing concerning the keys attributes. As you can see above, the attributes names in the "included" section are in camelcase (firstName, lastLogin, ...).

But when I execute the serializer on my route to retrieve a single instance of User, I get :

{
  "data": {
    "type": "user",
    "id": "1",
    "attributes": {
      "username": "gbu",
      "email": "gbu@example.com",
      "initials": null,
      "first_name": "...",
      "surname_prefix": null,
      "surname": "...",
      "enabled": true,
      "locked": false,
      "last_login": null
    }
  },
  "links": {
    "self": {
      "href": "/app_dev.php/admin/v1/user/1?access_token=ZmI4Nzc5YTlmOTk2Mjg3MDg4NzEwODY4N2NlNjEyOTViMTA4MTYyMjViZjAxZDY5ZWQ1Yzg0YjRmYmJjN2RhMf"
    }
  },
  "jsonapi": {
    "version": "1.0"
  }
}

As you can see, the names are transformed in snake case. it is due to the call in JsonAPiTransformer::serialization. It calls DataAttributesHelper::setResponseDataAttributes($this->mappings, $value) which in turn calls the method transformToValidMemberName.

But could this behavior be configurable ? Because my parser must now be aware of the snake case and the camelCase to construct my user object.

Thanks for your help.

nilportugues commented 8 years ago

@guiguiboy looks like a bug. Great information to dive in an fix this.

jschwartzenberg commented 8 years ago

I'm facing a similar issue here. @nilportugues you think you might be able to look into this or do you expect a pull request? In the last case, you happen to have a pointer where in the code to look for a solution?

nilportugues commented 8 years ago

Yeah sure you can do a PR. I'll be happy to merge.

You can set alias for all fields to force camelCase in the mapping files.

m1n0 commented 7 years ago

The camel case to underscore method is used all over the place, not that easy to refactor, so I tried to use the property alias trick in mapping file with no luck, would you please show an example how it should work? Thanks

m1n0 commented 7 years ago

ok I made 3 PRs to make this happen, initially I only make sure that Symfony consumes config for this, and that this config is passed on correctly. Currently this only supports snake_case (which is default) and keep_case, which does no case modifications. The respective PRs: https://github.com/nilportugues/symfony-jsonapi/pull/32 https://github.com/nilportugues/php-json-api/pull/91 https://github.com/nilportugues/php-api-transformer/pull/13

Please let me know if this needs further work.

trivago-makbarof commented 7 years ago

@nilportugues Any luck with this PR? We really like the bundle but we want to keep the attributes camel case