<p>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.</p>

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

<p>For resource on eager  loading, see:</p>

<ul>
<li><a href="https://craftcms.com/docs/templating/eager-loading-elements" rel="nofollow noreferrer">https://craftcms.com/docs/templating/eager-loading-elements</a></li>
<li><a href="https://straightupcraft.com/articles/examples-of-eager-loading-elements-in-twig-and-php" rel="nofollow noreferrer">https://straightupcraft.com/articles/examples-of-eager-loading-elements-in-twig-and-php</a></li>
</ul>

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

<pre><code>return [
    'elementType' =&gt; 'Entry',
    'criteria' =&gt; [
        'section' =&gt; 'directory',
        'relatedTo' =&gt; ['targetElement' =&gt; $category],
        'limit' =&gt; 1,
        'with' =&gt; ['country','port'],
    ],
</code></pre>

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

CC BY-SA 3.0
2016-12-17T00:28:19.647Z
2016-12-17T00:28:19.647Z
Jeremy Daalder
<p>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</p>

<p>Below is how I am getting the data in the elementAPI plugin</p>

<pre><code>'api/v2/country/&lt;slug:{slug}&gt;.json' =&gt; function($slug) {

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

        return [
            'country' =&gt; (string)$entry-&gt;country[0],
            'port' =&gt; (string)$entry-&gt;country[1],
            'title' =&gt; $entry-&gt;title,
            'mapinfo' =&gt; $entry-&gt;mapaddress,
            'url' =&gt; $entry-&gt;url
        ];
    },
];
},
</code></pre>

<p>The addition of </p>

<pre><code>'country' =&gt; (string)$entry-&gt;country[0],
'port' =&gt; (string)$entry-&gt;country[1],
</code></pre>

<p>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'.</p>

<p>Any ideas on speeding up would be very welcome.</p>

<plugin-elementapi>
Getting categories in elementAPI performance issues and help required
# Getting categories in elementAPI performance issues and help required

(Asked by: username_0 on 2016-12-16)

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/.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.

**Tags:** plugin-elementapi


---

## 1 answers

### Answer by username_1 on 2016-12-17. Score: 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:

https://craftcms.com/docs/templating/eager-loading-elements
https://straightupcraft.com/articles/examples-of-eager-loading-elements-in-twig-and-php

...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!


---

