Skip to content

IntegrationInterface Implementation

Rougin Gutib edited this page Dec 25, 2023 · 18 revisions

The IntegrationInterface implementation is another way of organizing the application code and make it reusable. Its concept is similar to the Components class but their difference is that the IntegrationInterface is not being used exclusively for Slytherin's core components.

With this, it is possible for defining the instances needed to an application first prior receiving the HTTP request. The usage of the IntegrationInterface is also used to support specified third-party packages for Slytherin.

Using the *Integration classes

Below is an example integration of the Routing component which is the RoutingIntegration. This integration will create a class that is based on the DispatcherInterface of the said component and will accept a RouterInterface from the configuration if provided:

namespace Rougin\Slytherin\Routing;

use Rougin\Slytherin\Container\ContainerInterface;
use Rougin\Slytherin\Integration\Configuration;
use Rougin\Slytherin\Integration\IntegrationInterface;
use Rougin\Slytherin\System;

class RoutingIntegration implements IntegrationInterface
{
    // ...

    /**
     * Defines the specified integration.
     *
     * @param  \Rougin\Slytherin\Container\ContainerInterface $container
     * @param  \Rougin\Slytherin\Integration\Configuration    $config
     * @return \Rougin\Slytherin\Container\ContainerInterface
     */
    public function define(ContainerInterface $container, Configuration $config)
    {
        $dispatcher = new Dispatcher;

        /** @var \Rougin\Slytherin\Routing\RouterInterface */
        $router = $config->get('app.router', new Router);

        if ($this->wants('fastroute'))
        {
            $dispatcher = new FastRouteDispatcher;
        }

        if ($this->wants('phroute'))
        {
            $dispatcher = new PhrouteDispatcher;
        }

        $container->set(System::DISPATCHER, $dispatcher);

        return $container->set(System::ROUTER, $router);
    }

    // ...
}

Note

All components in Slytherin have their own integration implementation (except for the Container component).

Example Code

To add the RoutingIntegration to an application, use the integrate method from the Application class prior to the run method:

 use Rougin\Slytherin\Application;
 use Rougin\Slytherin\Components;
+use Rougin\Slytherin\Configuration;
 use Rougin\Slytherin\Http\Response;
 use Rougin\Slytherin\Http\ServerRequest;
-use Rougin\Slytherin\Routing\Dispatcher;
 use Rougin\Slytherin\Routing\Router;
+use Rougin\Slytherin\Routing\RoutingIntegration;

 require 'vendor/autoload.php';

 $components = new Components;

+$config = new Configuration;
+
 // ...

 // Create a new router to add an HTTP route... ---
 
 // ...
+
+$config->set('app.router', $router);
 // -----------------------------------------------

 // ...then define it to a dispatcher ---
-$dispatcher = new Dispatcher($router);
-
-$components->setDispatcher($dispatcher);
+$items = array(new RoutingIntegration);
 // -------------------------------------

 // Lastly, run the application ------
-(new Application($components))->run();
+$app = new Application($components);
+
+$app->integrate($items, $config)->run();
 // ----------------------------------

Based on the sample code above, the IntegrationInterface implementation can coexist with the previously discussed implementations (e.g., ContainerInterface, Components). It only depends on the proposed folder structure or implementation of an application.

Using the Application as a Router

Using the IntegrationInterface, the Application class can also act as a Router (that is implemented in Rougin\Slytherin\Routing\RouterInterface) and uses the HttpIntegration and RoutingIntegration which can create a Slytherin application directly without specifying the said integrations manually. A separate guide for this special implementation can be found in the Application as a Router page.