Module Description
What does it do? Do you have a consumer (for instance a JavaScript application) that uses a 3rd party API?
* Does that API have all the CORS headers you need?
* Does that API have sufficient caching?
* Does it require an authentication key that you don't want to put in the clear in your JS app?
* Do you wish it returned something different?
This module will help with all those problems. Putting Drupal between your consumer and the 3rd party API will allow you to modify the requests to the 3rd party API and the responses from it.
Usage You will need to:
* Create the proxy plugin.
* Configure the server plugin.
* Profit.
Create the proxy plugin
In order to connect to a new API you will need to write a new plugin. Take for instance:
namespace Drupal\my_module\Plugin\api_proxy; use Drupal\api_proxy\Plugin\api_proxy\HttpApiCommonConfigs; use Drupal\api_proxy\Plugin\HttpApiPluginBase; use Drupal\Core\Form\SubformStateInterface; use Symfony\Component\HttpFoundation\Response; /** * The Example API. * * @HttpApi( * id = "api-slug", * label = @Translation("Example API"), * description = @Translation("Proxies requests to the Example API."), * serviceUrl = "https://api.example.org/v1", * ) */ final class Example extends HttpApiPluginBase { use HttpApiCommonConfigs; /** * {@inheritdoc} */ public function addMoreConfigurationFormElements(array $form, SubformStateInterface $form_state): array { $form['auth_token'] = $this->authTokenConfigForm($this->configuration); $form['more_stuff'] = ['#type' => 'textfield', '#title' => $this->t('Extra config')]; return $form; } /** * {@inheritdoc} */ protected function calculateHeaders(array $headers): array { $new_headers = parent::calculateHeaders($headers); // Modify & add new headers. Here you can add the auth token. Refer to your // APIs documentation for expected auth format. return $new_headers; } /** * {@inheritdoc} */ public function postprocessOutgoing(Response $response): Response { // Modify the response from the API. // A common problem is to remove the Transfer-Encoding header. // $response->headers->remove('transfer-encoding'); return $response; } } Configure the server plugin
Head to /admin/config/services/api-proxy/settings and you should see a configuration form for your proxy. Note that there will be some common configuration options plus the ones specific for this plugin you added in addMoreConfigurationFormElements.
Profit
In your consumer (JS application) instead of making requests to:
https://api.example.org/v1/the-resource/123?setting[foo]=bar&lorem=10
Make them against:
https://your-drupal-install.com/api-proxy/api-slug?_api_proxy_uri=the-resource%2F123%3Fsetting%5Bfoo%5D%3Dbar%26lorem%3D10
Note that you will need to URL encode the the-resource/123?setting[foo]=bar&lorem=10. This results into the-resource%2F123%3Fsetting%5Bfoo%5D%3Dbar%26lorem%3D10.
* Does that API have all the CORS headers you need?
* Does that API have sufficient caching?
* Does it require an authentication key that you don't want to put in the clear in your JS app?
* Do you wish it returned something different?
This module will help with all those problems. Putting Drupal between your consumer and the 3rd party API will allow you to modify the requests to the 3rd party API and the responses from it.
Usage You will need to:
* Create the proxy plugin.
* Configure the server plugin.
* Profit.
Create the proxy plugin
In order to connect to a new API you will need to write a new plugin. Take for instance:
namespace Drupal\my_module\Plugin\api_proxy; use Drupal\api_proxy\Plugin\api_proxy\HttpApiCommonConfigs; use Drupal\api_proxy\Plugin\HttpApiPluginBase; use Drupal\Core\Form\SubformStateInterface; use Symfony\Component\HttpFoundation\Response; /** * The Example API. * * @HttpApi( * id = "api-slug", * label = @Translation("Example API"), * description = @Translation("Proxies requests to the Example API."), * serviceUrl = "https://api.example.org/v1", * ) */ final class Example extends HttpApiPluginBase { use HttpApiCommonConfigs; /** * {@inheritdoc} */ public function addMoreConfigurationFormElements(array $form, SubformStateInterface $form_state): array { $form['auth_token'] = $this->authTokenConfigForm($this->configuration); $form['more_stuff'] = ['#type' => 'textfield', '#title' => $this->t('Extra config')]; return $form; } /** * {@inheritdoc} */ protected function calculateHeaders(array $headers): array { $new_headers = parent::calculateHeaders($headers); // Modify & add new headers. Here you can add the auth token. Refer to your // APIs documentation for expected auth format. return $new_headers; } /** * {@inheritdoc} */ public function postprocessOutgoing(Response $response): Response { // Modify the response from the API. // A common problem is to remove the Transfer-Encoding header. // $response->headers->remove('transfer-encoding'); return $response; } } Configure the server plugin
Head to /admin/config/services/api-proxy/settings and you should see a configuration form for your proxy. Note that there will be some common configuration options plus the ones specific for this plugin you added in addMoreConfigurationFormElements.
Profit
In your consumer (JS application) instead of making requests to:
https://api.example.org/v1/the-resource/123?setting[foo]=bar&lorem=10
Make them against:
https://your-drupal-install.com/api-proxy/api-slug?_api_proxy_uri=the-resource%2F123%3Fsetting%5Bfoo%5D%3Dbar%26lorem%3D10
Note that you will need to URL encode the the-resource/123?setting[foo]=bar&lorem=10. This results into the-resource%2F123%3Fsetting%5Bfoo%5D%3Dbar%26lorem%3D10.
Module Link
Project Usage
302
Security Covered
Covered By Security Advisory
Version Available
Production
Module Summary
This module acts as a proxy between a consumer (such as a JavaScript application) and a 3rd party API, allowing for modification of requests and responses, handling CORS headers, caching, authentication keys, and customizing returned data.
Data Name
api_proxy