Skip to content
Snippets Groups Projects
Commit 4923510e authored by Adriano Cori's avatar Adriano Cori
Browse files

8.x-2.x version for Drupal core >= 8.4

parent 4597b849
No related branches found
No related tags found
No related merge requests found
Showing
with 302 additions and 230 deletions
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
{ "name": "Adriano Cori", "email": "adriano.cori@bmeme.com" } { "name": "Adriano Cori", "email": "adriano.cori@bmeme.com" }
], ],
"require": { "require": {
"guzzle/guzzle": "^3.9" "drupal/core": ">=8.4",
"guzzlehttp/guzzle-services": "^1.1",
"gimler/guzzle-description-loader": "^0.0.4"
} }
} }
\ No newline at end of file
...@@ -3,4 +3,6 @@ type: module ...@@ -3,4 +3,6 @@ type: module
description: Manage Guzzle based HTTP Clients instances and configurations. description: Manage Guzzle based HTTP Clients instances and configurations.
core: 8.x core: 8.x
package: Web services package: Web services
configure: http_client_manager.preview configure: http_client_manager.preview
\ No newline at end of file dependencies:
- system (>=8.4)
\ No newline at end of file
...@@ -20,10 +20,16 @@ function http_client_manager_help($route_name, RouteMatchInterface $route_match) ...@@ -20,10 +20,16 @@ function http_client_manager_help($route_name, RouteMatchInterface $route_match)
$output .= '<p>' . t('Manage HTTP Clients instances and configurations.') . '</p>'; $output .= '<p>' . t('Manage HTTP Clients instances and configurations.') . '</p>';
return $output; return $output;
case 'http_client_manager.preview': case 'http_client_manager.settings':
$code = "<pre><code>\$settings['http_services_api']['your_service_api_id'] = [\n"; $code = "<pre><code>\$settings['http_services_api']['your_service_api_id'] = [\n";
$code .= " 'title' => 'Example API (Development)',\n"; $code .= " 'title' => 'Example API (Development)',\n";
$code .= " 'base_url' => 'http://dev.example.com/api',\n"; $code .= " 'api_path' => 'src/api/api_development.json',\n";
$code .= " 'config' => [\n";
$code .= " 'base_uri' => 'http://dev.example.com/api',\n";
$code .= " 'timeout' => 10,\n";
$code .= " 'connect_timeout' => 8,\n";
$code .= " 'debug' => 1,\n";
$code .= " ],\n";
$code .= "];</code></pre>"; $code .= "];</code></pre>";
$build = [ $build = [
......
...@@ -12,11 +12,6 @@ services: ...@@ -12,11 +12,6 @@ services:
class: Drupal\http_client_manager\HttpClient class: Drupal\http_client_manager\HttpClient
factory: http_client_manager.factory:get factory: http_client_manager.factory:get
http_client_manager.event_subscriber:
class: Drupal\http_client_manager\EventSubscriber\HttpClientManagerEventSubscriber
tags:
- { name: event_subscriber }
http_client_manager.swagger: http_client_manager.swagger:
class: Drupal\http_client_manager\HttpClientManagerSwagger class: Drupal\http_client_manager\HttpClientManagerSwagger
arguments: ["@http_client"] arguments: ["@http_client"]
\ No newline at end of file
...@@ -5,6 +5,6 @@ dependencies: { } ...@@ -5,6 +5,6 @@ dependencies: { }
id: find_post id: find_post
label: 'Find post' label: 'Find post'
service_api: example_services service_api: example_services
command_name: FindPosts command_name: FindPost
parameters: parameters:
postId: '1' postId: '1'
example_services: example_services:
title: "Example Services fake API" title: "[JSON] - Example Services fake API"
api_path: "src/api/example_services.json" api_path: "src/api/example_services.json"
base_url: "http://jsonplaceholder.typicode.com" config:
\ No newline at end of file base_uri: "http://jsonplaceholder.typicode.com"
example_services_yaml:
title: "[YAML] - Example Services fake API"
api_path: "src/api/example_services.yml"
config:
base_uri: "http://jsonplaceholder.typicode.com"
\ No newline at end of file
...@@ -14,4 +14,4 @@ http_client_manager_example.create_post: ...@@ -14,4 +14,4 @@ http_client_manager_example.create_post:
_controller: '\Drupal\http_client_manager_example\Controller\ExampleController::createPost' _controller: '\Drupal\http_client_manager_example\Controller\ExampleController::createPost'
_title: 'Create post' _title: 'Create post'
requirements: requirements:
_permission: 'access content' _permission: 'access content'
\ No newline at end of file
services: services:
example_api.http_client: example_api.http_client:
parent: http_client_manager.client_base parent: http_client_manager.client_base
arguments: ['example_services'] arguments: ['example_services']
\ No newline at end of file
http_client_manager_example.subscriber:
class: Drupal\http_client_manager_example\EventSubscriber\HttpClientManagerExampleSubscriber
tags:
- { name: event_subscriber }
...@@ -7,6 +7,7 @@ use Drupal\Core\Link; ...@@ -7,6 +7,7 @@ use Drupal\Core\Link;
use Drupal\http_client_manager\Entity\HttpConfigRequest; use Drupal\http_client_manager\Entity\HttpConfigRequest;
use Drupal\http_client_manager\HttpClientInterface; use Drupal\http_client_manager\HttpClientInterface;
use Drupal\http_client_manager_example\Response\FindPostsResponse; use Drupal\http_client_manager_example\Response\FindPostsResponse;
use GuzzleHttp\Command\Result;
use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerInterface;
/** /**
...@@ -60,13 +61,19 @@ class ExampleController extends ControllerBase { ...@@ -60,13 +61,19 @@ class ExampleController extends ControllerBase {
*/ */
public function findPosts($postId = NULL) { public function findPosts($postId = NULL) {
$client = $this->getClient(); $client = $this->getClient();
/** @var FindPostsResponse $response */
$response = $client->findPosts(['postId' => $postId]);
$post_link = TRUE; $post_link = TRUE;
$command = 'FindPosts';
$params = [];
if (!empty($postId)) { if (!empty($postId)) {
$post_link = FALSE; $post_link = FALSE;
$response = [$postId => $response]; $command = 'FindPost';
$params = ['postId' => $postId];
}
$response = $client->call($command, $params);
if (!empty($postId)) {
$response = [$postId => $response->toArray()];
} }
$build = []; $build = [];
...@@ -80,24 +87,24 @@ class ExampleController extends ControllerBase { ...@@ -80,24 +87,24 @@ class ExampleController extends ControllerBase {
/** /**
* Build Post response. * Build Post response.
* *
* @param \Drupal\http_client_manager_example\Response\FindPostsResponse $post * @param array $post
* The Post response object. * The Post response item.
* @param bool $post_link * @param bool $post_link
* TRUE for a "Read more" link, otherwise "Back to list" link. * TRUE for a "Read more" link, otherwise "Back to list" link.
* *
* @return array * @return array
* A render array of the post. * A render array of the post.
*/ */
protected function buildPostResponse(FindPostsResponse $post, $post_link) { protected function buildPostResponse(array $post, $post_link) {
$route = 'http_client_manager_example.find_posts'; $route = 'http_client_manager_example.find_posts';
$link_text = $post_link ? $this->t('Read more') : $this->t('Back to list'); $link_text = $post_link ? $this->t('Read more') : $this->t('Back to list');
$route_params = $post_link ? ['postId' => $post->getId()] : []; $route_params = $post_link ? ['postId' => $post['id']] : [];
$output = [ $output = [
'#type' => 'fieldset', '#type' => 'fieldset',
'#title' => $post->getId() . ') ' . $post->getTitle(), '#title' => $post['id'] . ') ' . $post['title'],
'body' => [ 'body' => [
'#markup' => '<p>' . $post->getBody() . '</p>', '#markup' => '<p>' . $post['body'] . '</p>',
], ],
'link' => [ 'link' => [
'#markup' => Link::createFromRoute($link_text, $route, $route_params) '#markup' => Link::createFromRoute($link_text, $route, $route_params)
......
<?php
namespace Drupal\http_client_manager_example\EventSubscriber;
use Drupal\http_client_manager\Event\HttpClientEvents;
use Drupal\http_client_manager\Event\HttpClientHandlerStackEvent;
use GuzzleHttp\Middleware;
use Psr\Http\Message\MessageInterface;
use Psr\Http\Message\RequestInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Class HttpClientManagerExampleSubscriber.
*/
class HttpClientManagerExampleSubscriber implements EventSubscriberInterface {
/**
* {@inheritdoc}
*/
static function getSubscribedEvents() {
return [
HttpClientEvents::HANDLER_STACK => ['onHandlerStack'],
];
}
/**
* This method is called whenever the http_client.handler_stack event is
* dispatched.
*
* @param \Drupal\http_client_manager\Event\HttpClientHandlerStackEvent $event
* The HTTP Client Handler stack event.
*/
public function onHandlerStack(HttpClientHandlerStackEvent $event) {
if ($event->getHttpServiceApi() != 'example_services') {
return;
}
$handler = $event->getHandlerStack();
$middleware = Middleware::mapRequest([$this, 'addExampleServiceHttpHeader']);
$handler->push($middleware, 'example_services');
}
/**
* Add example service HTTP Header.
*
* @param \Psr\Http\Message\RequestInterface $request
* The current Request object.
*
* @return MessageInterface
* Return an instance with the provided value for the specified header.
*/
public function addExampleServiceHttpHeader(RequestInterface $request) {
return $request->withHeader('X-EXAMPLE-HTTP-HEADER', 'example_services');
}
}
<?php
namespace Drupal\http_client_manager_example\Response;
use Guzzle\Service\Command\OperationCommand;
use Guzzle\Service\Command\ResponseClassInterface;
/**
* Class FindPostsResponse.
*
* @package Drupal\http_client_manager_example\Response
*/
class FindPostsResponse implements ResponseClassInterface {
/**
* The post author id.
*
* @var int
*/
protected $userId;
/**
* The post id.
*
* @var int
*/
protected $id;
/**
* The post title
*
* @var string
*/
protected $title;
/**
* The post body
*
* @var string
*/
protected $body;
/**
* {@inheritdoc}
*/
public static function fromCommand(OperationCommand $command) {
$results = $command->getResponse()->json();
if ($command->get('postId')) {
return new self($results);
}
$posts = [];
foreach($results as $result) {
$post = new self($result);
$posts[$post->getId()] = $post;
}
return $posts;
}
/**
* FindPostsResponse constructor.
*
* @param array $json
* The JSON response.
*/
public function __construct($json) {
$this->userId = $json['userId'];
$this->id = $json['id'];
$this->title = $json['title'];
$this->body = $json['body'];
}
/**
* Get user id.
*
* @return int
* The post author id.
*/
public function getUserId() {
return $this->userId;
}
/**
* Set user id.
*
* @param int $userId
* The post author id.
*/
public function setUserId($userId) {
$this->userId = $userId;
}
/**
* Get id.
*
* @return int
* The post id.
*/
public function getId() {
return $this->id;
}
/**
* Set id.
*
* @param int $id
* The post id.
*/
public function setId($id) {
$this->id = $id;
}
/**
* Get title.
*
* @return string
* The post title.
*/
public function getTitle() {
return $this->title;
}
/**
* Set title.
*
* @param string $title
* The post title.
*/
public function setTitle($title) {
$this->title = $title;
}
/**
* Get body.
*
* @return string
* The post body.
*/
public function getBody() {
return $this->body;
}
/**
* Set body.
*
* @param string $body
* The post body.
*/
public function setBody($body) {
$this->body = $body;
}
}
{ {
"name": "ExampleServicesApi", "name": "ExampleServicesApi",
"apiVersion": "2016-07-29", "apiVersion": "2.0",
"description": "Client wrapper for the Example Services API.", "description": "Client wrapper for the Example Services API.",
"includes" : [ "imports" : [
"resources/posts.json" "resources/posts.json"
] ]
} }
name: "[YAML] - ExampleServicesApi"
apiVersion: "2.0"
description: "Client wrapper for the Example Services API."
imports:
- "resources/posts.yml"
\ No newline at end of file
...@@ -5,37 +5,47 @@ ...@@ -5,37 +5,47 @@
"uri": "posts", "uri": "posts",
"summary": "Create post", "summary": "Create post",
"responseClass": "CreatePostOutput", "responseClass": "CreatePostOutput",
"content-type": {
"location": "header",
"default": "application/x-www-form-urlencoded"
},
"parameters": { "parameters": {
"title": { "title": {
"type": "string", "type": "string",
"location": "postField", "location": "body",
"description": "The post title", "description": "The post title",
"required": true "required": true
}, },
"body": { "body": {
"type": "string", "type": "string",
"location": "postField", "location": "body",
"description": "The post body", "description": "The post body",
"required": true "required": true
}, },
"userId": { "userId": {
"type": "string", "type": "string",
"location": "postField", "location": "body",
"description": "The post author id", "description": "The post author id",
"required": true "required": true
} }
} }
}, },
"FindPosts": { "FindPosts": {
"httpMethod": "GET",
"uri": "posts",
"summary": "Find posts",
"responseClass": "FindPostsOutput"
},
"FindPost": {
"httpMethod": "GET", "httpMethod": "GET",
"uri": "posts/{postId}", "uri": "posts/{postId}",
"summary": "Find posts", "summary": "Find posts",
"responseClass": "Drupal\\http_client_manager_example\\Response\\FindPostsResponse", "responseClass": "Post",
"parameters": { "parameters": {
"postId": { "postId": {
"location": "uri", "location": "uri",
"description": "Filter posts by id", "description": "Filter posts by id",
"required": false, "required": true,
"type": "string" "type": "string"
} }
} }
...@@ -56,6 +66,7 @@ ...@@ -56,6 +66,7 @@
}, },
"models": { "models": {
"CreatePostOutput": { "CreatePostOutput": {
"location": "json",
"type": "object", "type": "object",
"properties": { "properties": {
"title": { "title": {
...@@ -75,6 +86,34 @@ ...@@ -75,6 +86,34 @@
"type": "integer" "type": "integer"
} }
} }
},
"Post": {
"type": "object",
"properties": {
"userId": {
"location": "json",
"type": "integer"
},
"id": {
"location": "json",
"type": "integer"
},
"title": {
"location": "json",
"type": "string"
},
"body": {
"location": "json",
"type": "string"
}
}
},
"FindPostsOutput": {
"location": "json",
"type": "array",
"items": {
"$ref": "Post"
}
} }
} }
} }
operations:
FindPosts:
httpMethod: "GET"
uri: "posts"
summary: "Find all the available posts."
responseClass: "FindPostsOutput"
FindPost:
httpMethod: "GET"
uri: "posts/{postId}"
summary: "Find a single post by id."
responseClass: "Post"
parameters:
postId:
location: "uri"
description: "Filter posts by id"
required: true
type: "string"
FindComments:
httpMethod: "GET"
uri: "comments"
summary: "Find all post comments."
parameters:
postId:
location: "query"
description: "Filter comments by post id"
required: false
type: "integer"
models:
Post:
type: "object"
properties:
userId:
location: "json"
type: "integer"
id:
location: "json"
type: "integer"
title:
location: "json"
type: "string"
body:
location: "json"
type: "string"
FindPostsOutput:
type: "array"
location: "json"
items:
"$ref": "Post"
...@@ -48,14 +48,17 @@ class HttpClientManagerPreview extends ControllerBase { ...@@ -48,14 +48,17 @@ class HttpClientManagerPreview extends ControllerBase {
$header = [ $header = [
'id' => $this->t('ID'), 'id' => $this->t('ID'),
'title' => $this->t('Title'), 'title' => $this->t('Title'),
'base_url' => $this->t('Base URL'), 'base_uri' => $this->t('Base URI'),
'operations' => $this->t('Operations'), 'operations' => $this->t('Operations'),
]; ];
$rows = []; $rows = [];
foreach ($servicesApi as $api) { foreach ($servicesApi as $api) {
$row = array_intersect_key($api, $header); $rows[] = [
$row['operations']['data'] = $this->buildOperations($api); 'id' => $api['id'],
$rows[] = $row; 'title' => $api['title'],
'base_uri' => $api['config']['base_uri'],
'operations' => ['data' => $this->buildOperations($api)],
];
} }
return [ return [
......
...@@ -5,6 +5,7 @@ namespace Drupal\http_client_manager\Controller; ...@@ -5,6 +5,7 @@ namespace Drupal\http_client_manager\Controller;
use Drupal\Core\Controller\ControllerBase; use Drupal\Core\Controller\ControllerBase;
use Drupal\http_client_manager\Entity\HttpConfigRequest; use Drupal\http_client_manager\Entity\HttpConfigRequest;
use Drupal\vardumper\VarDumper\VarDumperDebug; use Drupal\vardumper\VarDumper\VarDumperDebug;
use GuzzleHttp\Command\Result;
use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerInterface;
/** /**
...@@ -62,6 +63,7 @@ class HttpConfigRequestController extends ControllerBase { ...@@ -62,6 +63,7 @@ class HttpConfigRequestController extends ControllerBase {
'commandName' => $commandName, 'commandName' => $commandName,
'parameters' => array_filter($config_request->getParameters()), 'parameters' => array_filter($config_request->getParameters()),
]; ];
/** @var Result $response */
$response = $config_request->execute(); $response = $config_request->execute();
if ($this->varDumper) { if ($this->varDumper) {
......
<?php
namespace Drupal\http_client_manager\Event;
/**
* Defines events for HTTP Client Manager clients.
*
* @package Drupal\http_client_manager\Event
*/
final class HttpClientEvents {
/**
* The name of the event fired when configuring client handlers stacks.
*
* This event allows you to add an handler to the stack whenever an HTTP
* client is created. The event listener method receives a
* \Drupal\http_client_manager\Event\HttpClientHandlerStackEvent instance.
*
* @Event
*/
const HANDLER_STACK = 'http_client.handler_stack';
}
<?php
namespace Drupal\http_client_manager\Event;
use GuzzleHttp\HandlerStack;
use Symfony\Component\EventDispatcher\Event;
/**
* Class HttpClientHandlerStackEvent.
*
* @package Drupal\http_client_manager\Event
*/
class HttpClientHandlerStackEvent extends Event {
/**
* The GuzzleHttp Handler stack.
*
* @var \GuzzleHttp\HandlerStack
*/
protected $handlerStack;
/**
* The HTTP Service API id.
*
* @var string
*/
protected $httpServiceApi;
/**
* HttpClientHandlerStackEvent constructor.
*
* @param \GuzzleHttp\HandlerStack $handler_stack
* The GuzzleHttp Handler stack.
* @param $http_service_api
* The HTTP Service Api id.
*/
public function __construct(HandlerStack $handler_stack, $http_service_api) {
$this->handlerStack = $handler_stack;
$this->httpServiceApi = $http_service_api;
}
/**
* Get Handler stack.
*
* @return \GuzzleHttp\HandlerStack
* The GuzzleHttp Handler stack.
*/
public function getHandlerStack() {
return $this->handlerStack;
}
/**
* Get HTTP Service Api id.
*
* @return string
* The HTTP Service Api id.
*/
public function getHttpServiceApi() {
return $this->httpServiceApi;
}
}
<?php
namespace Drupal\http_client_manager\EventSubscriber;
use Drupal\http_client_manager\HttpClientInterface;
use Guzzle\Service\Command\OperationCommand;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Guzzle\Common\Event;
/**
* Class HttpClientManagerEventSubscriber.
*
* @package Drupal\conftool
*/
class HttpClientManagerEventSubscriber implements EventSubscriberInterface {
/**
* {@inheritdoc}
*/
static function getSubscribedEvents() {
return [
'command.before_prepare' => array('onCommandBeforePrepare', -9000),
];
}
/**
* Command before-prepare event handler
*
* @param \Guzzle\Common\Event $event
* Event received
*/
public function onCommandBeforePrepare(Event $event) {
/** @var OperationCommand $command */
$command = $event['command'];
$description = $command->getClient()->getDescription();
$command->set(OperationCommand::HEADERS_OPTION, [
HttpClientInterface::HEADER_API => $description->getName(),
HttpClientInterface::HEADER_COMMAND => $command->getName(),
]);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment