Context
I'm currently upgrading a site from Drupal 7 to Drupal 8.
In the D7 version, there was a custom "proxy" module which served back-end services. Requests starting with a /service
prefix, such as http://my-drupal-domain/service/service-name?service-args
, were redirected to a custom index.php
inside a D7 module. This alternative index.php
called the minimal Drupal code needed : includes and drupal_bootstrap()
. Then, the custom module's function handled the request, sometimes using Drupal native functions (to manipulate users for example) and passing it to the target service. Finally, it returned the service response to the client.
Now I want to migrate this to Drupal 8.
I managed to code a custom REST controller, using a custom route :
my_module.rest_services:
path: '/service/{endpoint}'
defaults:
_controller: '\Drupal\my_module\Controller\ProxyController::index'
methods: [GET, POST, PUT, DELETE]
requirements:
_access: 'TRUE'
The ProxyController
, which extends Drupal\Core\Controller\ControllerBase
, is basically the same code that handled the requests in the previous site, converted to the OOP-way of D8.
Initial problem
My problem is that, using D8 routes and Symfony2 components, the response time for any request increase proportionally with the number of concurrent users compared to the D7 version. For 20 users, this latency is +1s with D8 than with a D7 minimal bootstrap... That's huge! (see chart below, for the exact same call to D7 with a custom minimal bootstrap and D8).
Is there a way to bypass some of D8 code to redirect requests directly to my controller ? Some sort of "minimal D8 bootstrap".
Or a way to improve D8 routes performance ?
Edit: need to cache file parsing
I just discovered Drupal 8 is not the only responsible for my performance loss! during the request handle process, in my module's code, I read and parse a YAML configuration file, using file_get_contents()
and Drupal\Component\Serialization\Yaml::decode()
. But Drupal does not cache the value by default : the file is read and parsed on each call. With 20 concurrent users, it can take up to 600ms...
I need to find a way to tell D8 "Read this config file once, parse it and cache the content so you don't have to read it again unless your cache is cleared".