Creating a custom wrapper API architecture based on GRASP patterns and SOLID principles

Introduction


Do you know what I do not like? - I do not like it when I have to get out of my cozy IDE once in a while to look in the API documentation of some service what parameters are there in the next entity. Well seriously, some services, if they create their own SDK / wrapper or whatever they have there, few people will bother to implement user interaction with the wrapper using a data converter (Data Mapper). But this can greatly simplify the life of simple mortal developers using the API.


In this regard, I decided to write your bikeown wrapper for the Bitrix24 API in PHP, as official - leaves much to be desired in the above plan.


In the article, I:


  • I will describe my way of thinking when thinking about architecture according to the principles of GRASP and SOLID
  • I will shoot myself in the leg, and then I will correct the situation
  • I will develop a prototype with the first entities and methods

Finding the Right Architecture


First of all, you need to decide how the user will use the wrapper. If you do not think it over at the initial stage, and immediately start sketching the architecture, then you can get quite what you wanted. So, you need to determine what functionality we will have a starting point, and begin the implementation in stages, pre-decomposing the task. If this principle is violated, then in the end you may succeed in desynchronizing the interfaces in one of the program modules, or maybe even in several, even if the project is done alone.


image


, - - , . 24.


, API « », - , OAuth2.0.
« », , , .


, . , .


, . , , , , , :


$leads = BX24Wrapper\Engine\WebHook::instane('https://b24-xxxxxx.bitrix24.ru/rest/1/********/')
    ->resources()
    ->leads()
    ->list(['STATUS' => 'NEW']);

$applicationEngine = BX24Wrapper\Engine\Application::instane('client_id', 'client_secret', 'access_token',...);
$leads = $applicationEngine
    ->resources()
    ->leads()
    ->list(['STATUS' => 'NEW']);
//      -  ,   
$responseFromSomeCall = $applicationEngine->get('crm.some.list', ['SOME' => 'VALUE']); 

, 2 (WebHook Application), « », . resources() , , (leads, deals, tasks…), — (list, add, update…). , … ? , , … .


, , UML- :




Engine\AbstractBasic — API.
Resources – , .
Resource\AbstractBasic — , API-, API-, .
Entity\AbstractBasic — -, API-.


, , Engine\AbstractBasic Resources , , . , , GRASP- « », .
_engine Resources – Resource\AbstractBasic . , , « ».


, - orders(), contacts() .. , Resources , « » SOLID- «/». , , .


, , , . !


, Engine Resources? Resources, , , , .


, ? IDE , — . , .


, :


$leads = Resource\Lead::instane(new Engine\WebHook('https://b24-xxxxxx.bitrix24.ru/rest/1/********/'))
    ->list(['STATUS' => 'NEW']);

$applicationEngine = BX24Wrapper\Engine\Application::instane('client_id', 'client_secret', 'access_token',...);
$leads = Resource\Lead::instane($applicationEngine)
    ->list(['STATUS' => 'NEW']);

$responseFromSomeCall = $applicationEngine->get('crm.some.list', ['SOME' => 'VALUE']);

, , , . , :




, , , , . , : → . , , API- , , , . .


image


, . : « ?» – - , «», , , , , , .


, Resource\AbstractBasic, , . — API- , – API- .
– «», Resource\AbstractBasic …



image


, . API-, , . . , , , …


! ( , ), ? ? , ?! .


Resource, — , !


$resource = Resource\Batch::instane(new Engine\WebHook('https://wtfkjg.ru/fdsgfds'));
$resource->sendBatchCalls([
    'lead_ids' => Resource\FindByComm::find(['type' => 'EMAIL', 'values' => ['79780001122'], 'entity_type' => 'LEAD']),
    'contacts' => Resource\Contact::list(['ID' => "\$result['lead_ids'][LEAD]"]),
]);

, - API-, . , Request. , .


image


, , Request. , …


, , ? ? , Resources, ? «» «/» - list, get ..


, , , Request- , . :


$engine = new Engine\WebHook('https://b24-xxxxxx.bitrix24.ru/rest/1/********/');

$leads = $engine->execute(Request\Lead\Items::all(['STATUS' => 'NEW'], ['ID' => 'DESC']));

$responseFromSomeGetCall = $engine->execute(Request\Custom::get('some.api.method', ['SOME' => 'PARAMS']));
$responseFromSomePostCall = $engine->execute(Request\Custom::post('some.api.method', ['SOME' => 'PARAMS']));

$response = $engine->execute([
    'lead_ids' => Request\FindByComm\Find::byPhone('79780001122', 'LEAD'),
    'contacts' => Request\Contact\Items::firstPage(['ID' => "\$result['lead_ids'][LEAD]"], ['ID' => 'ASC']),    
]);  



, (), execute , , http- . , API- . , -, .


, , , , - .


, :
-, , execute, mixed. , IDE , . , .. , .


You do that, right?


-, API- , 1 = 1 . - . , , , .



, API . , 24. !


GRASP SOLID, , .


GRASP:


  • : .
  • : Builder, .
  • : .
  • : .
  • : , , , .
  • : , . .
  • : Builder.
  • : Builder, .

SOLID:


  • : , .
  • /: API-, , , .
  • : , , , .
  • : , .
  • : , , , 0, .

, , . ? , , 100%, 90%, , . , , — . , …


-, GRASP SOLID - , . . - «», .


, .
: https://github.com/Dangetsu/bitrix24-api-wrapper
, , .


PHP 7.1, , .


:
slyshkin


:



All Articles