2

How to convert a custom Joomla 3 to Joomla 4, and use the Joomla 4 web services API?

I have an extension I wrote for J3 and with a bit of tweaking it works just fine in J4. I want to add web services to the extension since I am building a custom Android app for the site.

Do I need to implement additional code in my extension to have it properly work with the Joomla 4 web services API?

I will expand a bit on the component that I have written. It is a simple administrator component with 2 views, clients and records. The clients table is a simple table with id, client name, notes, and a published field. The records table is also a simple table with an id, a technician id, a client id, notes, time_in, time_out, and published.

This component is going to store a list of time in and time out records for a technician going on site for a given client for reporting purposes.

I have created an api folder for the component with a src folder similar to com_tags. Very simple, single display view and controller. I also have created web services plugin, again mimicking com_tags and simple changing the names of the extension and the controller name in the apiparseroute.

The error I am receiving in /administrator/logs/everything.php:

2022-06-15T16:20:44+00:00   CRITICAL xxx.xxx.xxx.xxx    error   Uncaught Throwable of type Joomla\CMS\Router\Exception\RouteNotFoundException thrown with message "Unable to handle request for route `v1/timetracker/clients`.". Stack trace: 
#0 [ROOT]/libraries/src/Application/ApiApplication.php(241): Joomla\CMS\Router\ApiRouter->parseApiRoute('GET')
#1 [ROOT]/libraries/src/Application/ApiApplication.php(104): Joomla\CMS\Application\ApiApplication->route()
#2 [ROOT]/libraries/src/Application/CMSApplication.php(278): Joomla\CMS\Application\ApiApplication->doExecute()
#3 [ROOT]/api/includes/app.php(54): Joomla\CMS\Application\CMSApplication->execute()
#4 [ROOT]/api/index.php(31): require_once('/home/customer/...')
#5 {main}

I am willing to share a zipped version of the component upon request if it helps since there is nothing in it that is proprietary. We are only using it for admins on the backend to have a visual reference. The majority of the work will be done through an Anroid app I am currently developing.

<?php
//WEB SERVICES PLUGIN
defined('_JEXEC') or die;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\CMS\Router\ApiRouter;

class PlgWebservicesTimetracker extends CMSPlugin
{
    protected $autoloadLanguage = true;

    public function onBeforeApiRoute(&$router)
    {
        $router->createCRUDRoutes(
            'v1/timetracker',
            'clients',
            ['component' => 'com_timetracker']
        );
    }
}

//ClientsController.php
<?php
namespace Joomla\Component\Timetracker\Api\Controller;

\defined('_JEXEC') or die;

use Joomla\CMS\MVC\Controller\ApiController;

class ClientsController extends ApiController
{
    protected $contentType = 'clients';
    protected $default_view = 'clients';
}

//JsonapiView.php
<?php
namespace Joomla\Component\Timetracker\Api\View\Clients;

\defined('_JEXEC') or die;

use Joomla\CMS\MVC\View\JsonApiView as BaseApiView;

class JsonapiView extends BaseApiView
{
    protected $fieldsToRenderItem = [
        'id',
        'business_name',
    ];
    protected $fieldsToRenderList = [
        'id',
        'business_name',
    ];
}

Stack Trace

2022-06-20T19:30:18+00:00
Uncaught Throwable of type Joomla\CMS\Router\Exception\RouteNotFoundException thrown with message "Unable to handle request for route `v1/timetracker/clients`.". 
Stack trace: #0 [ROOT]/libraries/src/Application/ApiApplication.php(241): Joomla\CMS\Router\ApiRouter->parseApiRoute('GET')
#1 [ROOT]/libraries/src/Application/ApiApplication.php(104): Joomla\CMS\Application\ApiApplication->route()
#2 [ROOT]/libraries/src/Application/CMSApplication.php(278): Joomla\CMS\Application\ApiApplication->doExecute()
#3 [ROOT]/api/includes/app.php(54): Joomla\CMS\Application\CMSApplication->execute()
#4 [ROOT]/api/index.php(31): require_once('/home/customer/...')
#5 {main}
2
  • 1
    Do post the relevant code. The error you're getting means the page is not found. Double check the URL you're trying to enter, the routes in your plugin and make sure that plugin is enabled.
    – Sharky
    Jun 16 at 5:53
  • @Sharky I added code examples for reference to my API files. Jun 16 at 15:50

1 Answer 1

0

The URL you're trying to enter or the defined route is wrong. You're trying to access v1/timetracker/clients but the route is defined as v1/timetracker. You should update it accordingly:

$router->createCRUDRoutes(
    'v1/timetracker/clients',
    'clients',
    ['component' => 'com_timetracker']
);
5
  • Uncaught Throwable of type Exception thrown with message "Component not found.". Stack trace: #0 Jun 20 at 3:48
  • Post the stack trace.
    – Sharky
    Jun 20 at 5:18
  • I added the stack trace. Jun 21 at 11:18
  • Did you post the right trace? It looks the same as the one before the change.
    – Sharky
    Jun 22 at 5:26
  • Yes, that was the trace immediately after updating the script. Jun 23 at 11:40

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.