Skip to content

Commit

Permalink
Merge pull request #33 from spotlibs/feature/exploration
Browse files Browse the repository at this point in the history
Client and ClientExternal Library
  • Loading branch information
m45adiwinata authored Jan 7, 2025
2 parents b50f423 + aa923c0 commit d7333b8
Show file tree
Hide file tree
Showing 6 changed files with 315 additions and 227 deletions.
1 change: 1 addition & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
<php>
<env name="APP_NAME" value="SPOTLIBS_MICROSERVICE"/>
<env name="APP_ENV" value="local"/>
<env name="APP_DEBUG" value="TRUE"/>
</php>

<coverage cacheDirectory=".phpunit.cache/code-coverage"
Expand Down
124 changes: 3 additions & 121 deletions src/Libraries/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,9 @@

namespace Spotlibs\PhpLib\Libraries;

use Carbon\Exceptions\InvalidTypeException;
use Exception;
use GuzzleHttp\Client as BaseClient;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\RequestOptions;
use Psr\Http\Message\ResponseInterface;
use Spotlibs\PhpLib\Libraries\ClientHelpers\Multipart;
use Symfony\Component\HttpKernel\Exception\HttpException;

/**
* ClientTimeoutUnit
Expand Down Expand Up @@ -111,42 +105,6 @@ public function setVerify(bool $verify): self
return $this;
}

/**
* Set request body
*
* @param array $body number of desired timeout
*
* @return self
*/
public function setRequestBody(array $body): self
{
$this->body = $body;
return $this;
}

/**
* Set request body in associative array
*
* @param string $form_type RequestOptions::FORM_PARAMS|JSON|MULTIPART|QUERY|...
*
* @return self
*/
public function setFormType(string $form_type): self
{
$allowed = [
RequestOptions::FORM_PARAMS,
RequestOptions::JSON,
RequestOptions::MULTIPART,
RequestOptions::QUERY,
RequestOptions::BODY
];
if (!in_array($form_type, $allowed)) {
throw new Exception('form type not allowed. supporting ' . implode(", ", $allowed));
}
$this->request_body_type = $form_type;
return $this;
}

/**
* Set request headers in associative array
*
Expand Down Expand Up @@ -182,90 +140,14 @@ public function injectResponseHeader(array $headers): self
*/
public function call(Request $request): ResponseInterface
{
$body = [];
if (!empty($this->body)) {
$this->checkMultipartBody();
$body = [
$this->request_body_type => $this->body
];
}
$options = ['timeout' => $this->timeout];
$options = array_merge($options, $body);
$options = ['timeout' => $this->timeout, 'verify' => $this->verify];
foreach ($this->requestHeaders as $key => $header) {
$request->withHeader($key, $header);
$request = $request->withHeader($key, $header);
}
$response = $this->send($request, $options);
foreach ($this->responseHeaders as $key => $header) {
$response->withHeader($key, $header);
$response = $response->withHeader($key, $header);
}
return $response;
}

/**
* Check and setup multipart request body if form type is multipart
*
* @return void
*/
private function checkMultipartBody(): void
{
if ($this->request_body_type == RequestOptions::MULTIPART) {
$temp = [];
$key_of_contents = [];
foreach ($this->body as $key => $b) {
if (! $b instanceof Multipart) {
throw new InvalidTypeException('Request body does not comply multipart form-data structure');
}
if (is_array($b->contents)) {
$key_of_contents[] = $key;
/**
* Check if contents is array of files
*
* @var array $b->contents
*/
if (isset($b->contents[0]) && $b->contents[0] instanceof \Illuminate\Http\UploadedFile) {
$z = $b->contents;
/**
* Array $b->contents
*
* @var \Illuminate\Http\UploadedFile[] $z
*/
foreach ($z as $v) {
/**
* Multipart
*
* @var \Illuminate\Http\UploadedFile $v multipart
*/
$y = new Multipart(['name' => $b->name . '[]', 'headers' => ['Content-Type' => $v->getMimeType()]]);
$y->contents = fopen($v->getRealPath(), 'r');
array_push($temp, $y->toArray());
}
}
} else {
$x = $this->body[$key];
/**
* Multipart
*
* @var Multipart $x multipart
*/
if ($x->contents instanceof \Illuminate\Http\UploadedFile) {
$z = $x->contents;
/**
* Uploaded file
*
* @var \Illuminate\Http\UploadedFile $z uploaded file
*/
$x->contents = fopen($z->getRealPath(), 'r');
}
$this->body[$key] = $x->toArray();
}
}
if (count($temp) > 0) {
foreach ($key_of_contents as $key) {
unset($this->body[$key]);
}
$this->body = array_values($this->body);
$this->body = array_merge($this->body, $temp);
}
}
}
}
185 changes: 185 additions & 0 deletions src/Libraries/ClientExternal.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
<?php

/**
* PHP version 8
*
* @category Library
* @package Libraries
* @author Made Mas Adi Winata <m45adiwinata@gmail.com>
* @license https://mit-license.org/ MIT License
* @version GIT: 0.3.7
* @link https://github.com/spotlibs
*/

declare(strict_types=1);

namespace Spotlibs\PhpLib\Libraries;

use GuzzleHttp\Client as BaseClient;
use GuzzleHttp\Psr7\MultipartStream;
use GuzzleHttp\Psr7\Request;
use Psr\Http\Message\ResponseInterface;
use Spotlibs\PhpLib\Logs\Log;

/**
* ClientTimeoutUnit
*
* Name for HTTP Client timeout unit
*
* @category HttpClient
* @package Client
* @author Made Mas Adi Winata <m45adiwinata@gmail.com>
* @license https://mit-license.org/ MIT License
* @link https://github.com/spotlibs
*/
class ClientExternal extends BaseClient
{
/**
* Timeout in seconds, default is 10 seconds
*
* @var float $timeout
*/
public float $timeout = 10;
/**
* Set to true to enable SSL certificate verification and use the default CA bundle provided by operating system
*
* @var bool $verify
*/
public bool $verify = false;
/**
* Request body, set according to the request
*
* @var array $body
*/
protected array $body = [];
/**
* Request header if only headers are not set in the request. Will be appended on call method
*
* @var array $requestHeaders
*/
protected array $requestHeaders = [];
/**
* Customize response header
*
* @var array $responseHeaders
*/
protected array $responseHeaders = [];
/**
* Body type of the
*
* @var array $responseHeaders
*/
protected string $request_body_type = 'json';

/**
* Create a new Client instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}

/**
* Set the timeout for Http Client
*
* @param float $timeout number of desired timeout
*
* @return self
*/
public function setTimeout(float $timeout): self
{
$this->timeout = $timeout;
return $this;
}

/**
* Set verify
*
* @param bool $verify number of desired timeout
*
* @return self
*/
public function setVerify(bool $verify): self
{
$this->verify = $verify;
return $this;
}

/**
* Set request headers in associative array
*
* @param array<string[]> $headers example: ['Content-Type' => ['application/json']]
*
* @return self
*/
public function injectRequestHeader(array $headers): self
{
$this->requestHeaders = $headers;
return $this;
}

/**
* Set response headers in associative array
*
* @param array<string[]> $headers example: ['Content-Type' => ['application/json']]
*
* @return self
*/
public function injectResponseHeader(array $headers): self
{
$this->responseHeaders = $headers;
return $this;
}

/**
* Set the timeout for Http Client
*
* @param Request $request HTTP Request instance
*
* @return ResponseInterface
*/
public function call(Request $request): ResponseInterface
{
$startime = microtime(true);
$options = ['timeout' => $this->timeout, 'verify' => $this->verify];
foreach ($this->requestHeaders as $key => $header) {
$request = $request->withHeader($key, $header);
}
if (!$request->hasHeader('Content-Type')) {
$request = $request->withHeader('Content-Type', 'application/json');
}
$response = $this->send($request, $options);
foreach ($this->responseHeaders as $key => $header) {
$response = $response->withHeader($key, $header);
}
$elapsed = microtime(true) - $startime;
if (env('APP_DEBUG', false)) {
$request->getBody()->rewind();
if (strlen($reqbody = $request->getBody()->getContents()) > 5000) {
$reqbody = "more than 5000 characters";
}
if (strlen($respbody = $response->getBody()->getContents()) > 5000) {
$respbody = "more than 5000 characters";
}
$logData = [
'host' => $request->getUri()->getHost(),
'url' => $request->getUri()->getPath(),
'request' => [
'headers' => $request->getHeaders(),
'body' => json_decode($reqbody, true)
],
'response' => [
'headers' => $response->getHeaders(),
'body' => json_decode($respbody, true)
],
'responseTime' => round($elapsed * 1000),
'memoryUsage' => memory_get_usage()
];
$response->getBody()->rewind();
Log::activity()->info($logData);
}
return $response;
}
}
41 changes: 0 additions & 41 deletions src/Libraries/ClientHelpers/Multipart.php

This file was deleted.

Loading

0 comments on commit d7333b8

Please sign in to comment.