restcakephpcakephp-2.2

Remove resource wrapper from CakePHP REST API JSON


My question is similar to this one. I understand the answer given there. The OP of that question doesn't seem to have my issue.

I am using CakePHP 2.2.3. I am fetching a resource like this:

http://cakephpsite/lead_posts.json

and it returns results like this:

[
    {
        "LeadPost": {
            "id": "1",
            "fieldA": "blah",
            "fieldB": "blah2",
        }
    {
        "LeadPost": {
            "id": "1",
            "fieldA": "blah",
            "fieldB": "blah2"
        }
    }
]

See the LeadPost wrapper on each object? I'm not sure why it's there. I want to remove it.

The LeadPost model extends AppModel and is otherwise empty.

LeadPostsController.php

class LeadPostsController extends AppController {

    public $components = array('RequestHandler');

    public function index() {
        $records = $this->LeadPost->find('all', ['limit' => 20]);
        $this->set(array(
            'leadposts' => $records,
            '_serialize' => 'leadposts'
        ));
    }
}

My routing is very simple:

Router::mapResources('lead_posts');
Router::parseExtensions();

Solution

  • Use the Hash utility to rewrite the results returned before setting the data for the View:-

    class LeadPostsController extends AppController {
    
        public $components = array('RequestHandler');
    
        public function index() {
            $records = $this->LeadPost->find('all', ['limit' => 20]);
            $this->set(array(
                'leadposts' => Hash::extract($records, '{n}.LeadPost'),
                '_serialize' => 'leadposts'
            ));
        }
    }
    

    Here Hash::extract($records, '{n}.LeadPost') will rewrite your array so that the LeadPost index is removed. It won't maintain the original array indexes, but unless you've messed with them in an afterFind callback should be the same.

    You could do this in the Model's afterFind as burzum suggests, but it feels more natural to me to do this in the Controller as we are specifically preparing the data for the View.