Is there some way I can split the element-api.php file into separate files and import them all? It's getting quite long and unwieldy.
1 Answers
Sure – the element-api.php config file is just plain ol' PHP, and the functions that make up the individual endpoints (e.g. 'news.json' => function () { ...) doesn't necessarily have to be declared inside that file.
One way to split up the file would be to create one PHP class per element type or section. You could compose these classes however you'd like, but something like the below would work (this is an example file containing two endpoints for the news section, and the example assumes that the file is saved under /config/endpoints/News.php):
<?php
namespace config\endpoints;
use craft\elements\Entry;
use craft\helpers\UrlHelper;
class News {
public static function index()
{
return [
'elementType' => Entry::class,
'criteria' => ['section' => 'news'],
'transformer' => function(Entry $entry) {
...
}
];
}
public static function view($entryId)
{
return [
'elementType' => Entry::class,
'criteria' => ['id' => $entryId],
'one' => true,
'transformer' => function(Entry $entry) {
...
}
];
}
}
The next step is to make the file available to the element-api.php config file. One way to do it, is to simply include() it at the top of the element-api.php file:
include __DIR__ . '/endpoints/News.php';
Then, you can add the endpoints from the News endpoint class to the config in element-api.php, i.e.:
<?php
include __DIR__ . '/endpoints/News.php';
use config\endpoints\News;
return [
'endpoints' => [
// use an anonymous function to prevent errors when running via cli
'news.json' => function () {
return News::index();
},
'news/<entryId:\d+>.json' => function ($entryId) {
return News::view($entryId);
},
],
];
If you want to take this a step further, a much nicer approach than using include() is to have Composer autoload your endpoint classes by adding the below to your composer.json file (again, this assumes that the custom endpoint classes live under /config/endpoints/):
"autoload": {
"psr-4": {
"config\\endpoints\\": "config/endpoints"
}
},
After editing your composer.json file, make sure to regenerate the autoloader by running the following from your command line (root of project, same directory where you keep your composer.json:
composer dump-autoload -o
Then, you can strip out the include() statement(s) in your element-api.php file, because Composer will autoload all the classes under /config/endpoints.
Finally, to make things super clean you could of course create a custom Yii Module (or a Craft plugin) to contain your endpoint classes. This would also avoid having to manually add the classpath to the composer.json file, for the autoloading.
- 639
- 4
- 13
- 22,361
- 3
- 38
- 69
One question: why does it need the anonymous function when a parameter is passed, what is the reason
– Urs Nov 12 '19 at 19:15'news/<entryId:\d+>.json' => News::view($entryId);won't work?