1

Is it possible to create a webservice and API access for my own component if the component file structure is not setup like this and uses namespace based classes?

https://docs.joomla.org/J4.x:Developing_an_MVC_Component/Developing_a_Basic_Component

My component is still using the style described like here: https://docs.joomla.org/Model-View-Controller

This documentation says API access is working with the default MVC Layer: https://docs.joomla.org/J4.x:Adding_an_API_to_a_Joomla_Component

I thought i'm using it. What is the default MVC Layer?

2 Answers 2

2

You can use virtually any component structure you want as long as Joomla can dispatch the component. You can use the J3 style single entry file. You can use the J4 service provider while still using the old entry file. Some of this is mentioned in this answer. You can use different component structure per application, e.g. you can keep using J3 structure in frontend/backend but use J4 structure in API application. There are many possible combinations.

That said, J3 style components work fine in API application. You can put a [component].php file in api/components/com_[component] directory and it will be executed as long as you correctly register the routes using a Webservices plugin.

0

I managed to get it working. What was important for me was to create the API provider registration in a way that it only gets triggered when an API call is made, so the component MVC structure can stay the same. I only needed to create a model and JsonapiView for the needed CRUD calls.

Service Provider

return new class implements ServiceProviderInterface {
    public function register(Container $container)
    {
        $container->registerServiceProvider(new MVCFactory('\\Joomla\\Component\\Mycomp'));
        $container->registerServiceProvider(new ComponentDispatcherFactory('\\Joomla\\Component\\Mycomp'));

        $container->set(
            ComponentInterface::class,
            static function (Container $container)
            {
                $component = new MycompComponent($container->get(ComponentDispatcherFactoryInterface::class));
                // $component->setRouterFactory($container->get(RouterFactoryInterface::class));

                return $component;
            }
        );       
    }
};

Component Class (src/Extensions/MycompComponent.php)

namespace Joomla\Component\Mycomp\Administrator\Extension;

use Joomla\CMS\Factory;
use Psr\Container\ContainerInterface;
use Joomla\CMS\Extension\ComponentInterface;
use Joomla\CMS\Dispatcher\DispatcherInterface;
use Joomla\CMS\Application\CMSApplicationInterface;
use Joomla\CMS\Dispatcher\ComponentDispatcherFactoryInterface;
use Joomla\CMS\Dispatcher\LegacyComponentDispatcher;

\defined('JPATH_PLATFORM') or die;

class MycompComponent implements ComponentInterface {
    private $dispatcherFactory;

    public function __construct(ComponentDispatcherFactoryInterface $dispatcherFactory)
    {
        $this->dispatcherFactory = $dispatcherFactory;
    }

    public function getDispatcher(CMSApplicationInterface $application): DispatcherInterface
    {
        // use J4 Dispatcher only for API calls
        if ($application->isClient('api')) {
            return $this->dispatcherFactory->createDispatcher($application);
        } else {
            return new LegacyComponentDispatcher($application);
        }
    }

    public function boot(ContainerInterface $container)
    {
    }

    // no idea what this is for :)
    public function validateSection($section, $item = null)
    {
        return;
    }

    public function getContexts(): array
    {
        Factory::getLanguage()->load('com_mycomp', JPATH_ADMINISTRATOR);

        $contexts = [
        ];

        return $contexts;
    }
}
7
  • This is not a good concept and can lead to unexpected results. The right place to change what dispatcher is used is in the getDispatcher() method of your component where the application instance if passed down.
    – Sharky
    Commented Feb 25, 2023 at 14:05
  • My comp has no getDispatcher method. Is there an simple example for this?
    – maidan
    Commented Feb 25, 2023 at 14:16
  • Have you read the linked answer in my answer? It does explain where the method comes from. Essentially it's the class implementing Joomla\CMS\Component\ComponentInterface (referenced as UsersComponent in your snippet). And some information about dispatchers.
    – Sharky
    Commented Feb 25, 2023 at 14:38
  • yeah, I tried but getting Resource 'Joomla\\CMS\\Dispatcher\\ComponentDispatcherFactoryInterface' has not been registered with the container. Very intransparent comparing to Laravel for me atm.
    – maidan
    Commented Feb 25, 2023 at 14:49
  • I updated my answer. Please let me know if that would be a better approach. Thanks.
    – maidan
    Commented Feb 25, 2023 at 15:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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