0

I am using elementAPI to get data from a directory. The items listed in the directory have two categories assigned: Category level 1 country Category level 2 region

Below is how I am getting the data in the elementAPI plugin

'api/v2/country/<slug:{slug}>.json' => function($slug) {

$criteria = craft()->elements->getCriteria(ElementType::Category);
$criteria->slug = $slug;
$category = $criteria->first();
return [
    'elementType' => 'Entry',
    'criteria' => [
        'section' => 'directory',
        'relatedTo' => ['targetElement' => $category],
        'limit' => 1,
    ],
    'transformer' => function(EntryModel $entry) {

        return [
            'country' => (string)$entry->country[0],
            'port' => (string)$entry->country[1],
            'title' => $entry->title,
            'mapinfo' => $entry->mapaddress,
            'url' => $entry->url
        ];
    },
];
},

The addition of

'country' => (string)$entry->country[0],
'port' => (string)$entry->country[1],

adds 1.5 seconds to the request, compared to not putting them in which comes in at .656ms. It seems the category data is already requested outside of the transformer but i cant see how to get the category array into the transformer. I also can't see why the specifying the categories in the transformer is so 'expensive'.

Any ideas on speeding up would be very welcome.

1

I'm no expert on the elementAPI, and a better answer will most likely come, but the country and port fields are relations to different elements (i.e. categories)....so Craft by default uses lazy loading to load this data only when it is called on by default, as I understand it. And that would probably be why the execution time jumps up.

What you really want to do, I think, is eager load this data as part of your initial query.

For resource on eager loading, see:

...so the question is, can you eager load in the element API? I am not sure, but I'd suggest adding the with part to your criteria and trying it! I'm just guessing on the syntax here, but it looks like:

return [
    'elementType' => 'Entry',
    'criteria' => [
        'section' => 'directory',
        'relatedTo' => ['targetElement' => $category],
        'limit' => 1,
        'with' => ['country','port'],
    ],

...would be worth trying. My gut feeling is this will work and will distinctly lower your execution time over the lazy loading way, but I'd love to get a report back!

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.