fe3dback/bapie

This package is abandoned and no longer maintained. No replacement package was suggested.

Bitrix Simple API components

v0.2.2 2018-08-29 09:10 UTC

This package is auto-updated.

Last update: 2019-08-01 19:54:55 UTC


README

this package in dev, do not use in production!

Lib for make simple and powerful api over bitrix cms.

Features:

  • auto API root detection
  • routes from symfony
  • middleware compatible with PSR-7 middleware dispatcher.
  • data validation, see list
  • bitrix integration (map, Result, $APPLICATION)

Example of usage

  1. make api entry point at $PROJECT_ROOT. For example %ROOT%/api/public/v1/index.php
use Bitrix\Main\Error;
use Fe3dback\Bapie\Common\ActionResult;
use Fe3dback\Bapie\Helpers\Routing;
use Fe3dback\Bapie\Middleware\RateLimit;
use Fe3dback\Bapie\Request;
use Fe3dback\Bapie\Scope;
use Respect\Validation\Validator;

$bsDir = dirname(__DIR__, 1) . '/.bootstrap';
require sprintf('%s/load.php', $bsDir);

$scope = new Scope(Routing::getPrefixFromDirectory(__DIR__));

// we can set any numbers of middleware, for example limit request rate
$scope->withMiddleware([
    new RateLimit(3, 1),
]);


// define API route (/api/public/v1/common/available-cities)
// our API can be described in external class AvailableCities::class. See examples for details..
$scope->on('common/available-cities', \ACME\APIHandlers\v1\Common\AvailableCities::class);

// define API route (/api/public/v1/lead)
$scope->on('lead', function (): ActionResult {

    // this data {"test":123} will be in Response of API call
    $result = new ActionResult();
    $result->setData([
        'test' => 123
    ]);
    
    // we can define any count of errors
    $result->addError(new Error('test'));
    $result->addError(new Error('123'));
    
    // every API route should return ActionResult object.
    return $result;
});

// define API route (/api/public/v1/lead/create)
$scope->on('lead/create', function (Request $request): ActionResult {

    $result = new ActionResult();

    // Request object is data helper for API
    // for example we can get validated whitelist of variables from $_REQUEST
    $validateResult = $request->map([
        'phone' => Validator::callback(function ($val) {
            // any custom handler
            return \Lean\Phone\Helper::getPhoneFromString($val);
        }),
        'name' => Validator::alpha()->startsWith('h')->length(1, 8)
    ]);

    // we should check validation result after each map/get
    if (!$validateResult->isSuccess()) {
        $result->setValidationErrors($validateResult);
        return $result;
    }

    // if validation is ok, in getData method we can get array of variables
    $params = $validateResult->getData();
    
    // set this variables to API output
    $result->setData([
        'lead' => [
            'phone' => $params['phone'],
            'name' => $params['name']
        ]
    ]);
    return $result;
});

$scope->run();

Make bootstrap script with common loader code:

%ROOT%/api/.bootstrap/load.php

/** @var CMain $APPLICATION */

$_SERVER['DOCUMENT_ROOT'] = dirname(__DIR__, 2);
$DOCUMENT_ROOT = $_SERVER['DOCUMENT_ROOT'];

define('NO_KEEP_STATISTIC', true);
define('BX_NO_ACCELERATOR_RESET', true);

require $_SERVER['DOCUMENT_ROOT']. '/bitrix/modules/main/include/prolog_before.php';

header(vsprintf('Access-Control-Allow-Origin: %s', [
    '*'
]));

test API:

https://my-project.loc/api/v1/public/lead or https://my-project.loc/api/v1/public/lead/create

Response example with error:

{
    "validation": {
        "name": [
            "name must contain only letters (a-z)",
            "name must start with (\"h\")",
            "name must have a length between 1 and 8"
        ]
    },
    "error": true,
    "http_code": 503,
    "message": "name must contain only letters (a-z), name must start with (\"h\"), name must have a length between 1 and 8"
}

Handle API in ActionClass

// ... in api scope file
$scope->on('common/available-cities', \ACME\APIHandlers\v1\Common\AvailableCities::class);
// ... in api scope file
namespace ACME\APIHandlers\v1\Common;

use Fe3dback\Bapie\Action;
use Fe3dback\Bapie\Common\ActionResult;
use Fe3dback\Bapie\Request;

class AvailableCities extends Action
{
    public function __invoke(Request $request): ActionResult
    {
        $result = new ActionResult();
        
        // get all data from some internal api. 
        // Example: getAllTitles - this method return array 
        // ('Moscow', 'Aksaj', 'New-Yourk', ..)
        $result->setData(\ACME\Regions\Cities::getAllTitles());
        
        return $result;
    }
}