PHP code example of nvmcommunity / alchemist-restful-api

1. Go to this page and download the library: Download nvmcommunity/alchemist-restful-api library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

nvmcommunity / alchemist-restful-api example snippets




use Nvmcommunity\Alchemist\RestfulApi\Common\Integrations\AlchemistQueryable;
use Nvmcommunity\Alchemist\RestfulApi\FieldSelector\Handlers\FieldSelector;
use Nvmcommunity\Alchemist\RestfulApi\ResourceFilter\Handlers\ResourceFilter;
use Nvmcommunity\Alchemist\RestfulApi\ResourceFilter\Objects\FilteringRules;
use Nvmcommunity\Alchemist\RestfulApi\ResourcePaginations\OffsetPaginator\Handlers\ResourceOffsetPaginator;
use Nvmcommunity\Alchemist\RestfulApi\ResourceSearch\Handlers\ResourceSearch;
use Nvmcommunity\Alchemist\RestfulApi\ResourceSort\Handlers\ResourceSort;
/**
 * Example of Order Api Query
 */
class OrderApiQuery extends AlchemistQueryable
{
    /**
     * @param FieldSelector $fieldSelector
     * @return void
     */
    public static function fieldSelector(FieldSelector $fieldSelector): void
    {
        $fieldSelector->defineFieldStructure([
            'id',
            'order_date',
            'order_status',
            'order_items' => [
                'item_id',
                'product_id',
                'price',
                'quantity'
            ]
        ]);
    }

    /**
     * @param ResourceFilter $resourceFilter
     * @return void
     */
    public static function resourceFilter(ResourceFilter $resourceFilter): void
    {
        $resourceFilter->defineFilteringRules([
            FilteringRules::String('product_name', ['eq', 'contains']),
            FilteringRules::Date('order_date', ['eq', 'lte', 'gte'], ['Y-m-d']),
            FilteringRules::Integer('product_id', ['eq']),
            FilteringRules::Boolean('is_best_sales', ['eq']),
        ]);
    }

    /**
     * @param ResourceOffsetPaginator $resourceOffsetPaginator
     * @return void
     */
    public static function resourceOffsetPaginator(ResourceOffsetPaginator $resourceOffsetPaginator): void
    {
        $resourceOffsetPaginator
            ->defineDefaultLimit(10)
            ->defineMaxLimit(1000);
    }

    /**
     * @param ResourceSearch $resourceSearch
     * @return void
     */
    public static function resourceSearch(ResourceSearch $resourceSearch): void
    {
        $resourceSearch
            ->defineSearchCondition('product_name');
    }

    /**
     * @param ResourceSort $resourceSort
     * @return void
     */
    public static function resourceSort(ResourceSort $resourceSort): void
    {
        $resourceSort
            ->defineDefaultSort('id')
            ->defineDefaultDirection('desc')
            ->defineSortableFields(['id', 'created_at']);
    }
}



use Nvmcommunity\Alchemist\RestfulApi\AlchemistRestfulApi;

// Assuming that the input parameters are passed in from the request input
$input = [
    'fields' => 'id,order_date,order_status,order_items{item_id,product_id,price,quantity}',
    'filtering' => [
        'order_date:lte' => '2023-02-26',
        'product_name:contains' => 'clothes hanger'
    ],
    'search' => 'clothes hanger',
    'sort' => 'id',
    'direction' => 'desc',
    'limit' => 10,
    'offset' => 0,
];

$restfulApi = AlchemistRestfulApi::for(OrderApiQuery::class, $input);

// Check if the input parameters are not valid, the validator will collect all errors and return them to you.
if (! $restfulApi->validate($errorBag)->passes()) {
    // var_dump(json_encode($errorBag->getErrors()));
    
    echo "validate failed"; die();
}

// Get all string fields that user want to retrieve
$restfulApi->fieldSelector()->flatFields();

// Get all filtering conditions that client passed in
$restfulApi->resourceFilter()->filtering();

$offsetPaginate = $restfulApi->resourceOffsetPaginator()->offsetPaginate();

// Get pagination limit and offset
$offsetPaginate->getLimit();
$offsetPaginate->getOffset();

$search = $restfulApi->resourceSearch()->search();

// Get search condition (defined in the API class) and search value (provided by user)
$search->getSearchCondition();
$search->getSearchValue();

$sort = $restfulApi->resourceSort()->sort();

// Get sort field and direction
$sort->getSortField();
$sort->getDirection();

use Nvmcommunity\Alchemist\RestfulApi\AlchemistRestfulApi;

$restfulApi = new AlchemistRestfulApi([
    // The fields are passed in from the request input, fields are separated by commas, and subsidiary fields
    // are enclosed in `{}`.
    'fields' => 'id,order_date,order_status,order_items{item_id,product_id,price,quantity}'
]);

// Call `$restfulApi->fieldSelector()` to start the field selector builder, then your API definitions can be
// defined based on the chain of builder.
$fieldSelector = $restfulApi->fieldSelector()
    // If no field is passed up by the API Client, the default field will present.
    ->defineDefaultFields(['id'])
    
    // Your API client can be able to retrieve any fields in the list
    ->defineFieldStructure([
            'id',
            'order_date',
            'order_status',
            'order_items' => [
                'item_id',
                'product_id',
                'price',
                'quantity'
            ]
        ]);

// The important thing here is that your API will be rigorously checked by the validator, which will check things like
// whether the selected fields are in the list of "selectable" fields, the same for subsidiary fields, and also
// whether your API client is selecting subsidiary fields on atomic fields that do not have subsidiary fields,
// for example: "id{something}", where id is an atomic field and has no subsidiary fields.
if (! $restfulApi->validate($errorBag)->passes()) {
    // var_dump(json_encode($errorBag->getErrors()));
    
    echo "validate failed"; die();
}

// Finally, what you will receive by call the `$fieldSelector->fields()` method is a list of field objects, and everything has been carefully checked.

// Combine with the use of an ORM/Query Builder

$result = ExampleOrderQueryBuilder::select($fieldSelector->flatFields())->get();

// For other purposes, use `$fieldSelector->fields()` to obtain a complete map list of field object.

var_dump($fieldSelector->fields());

use Nvmcommunity\Alchemist\RestfulApi\AlchemistRestfulApi;
use Nvmcommunity\Alchemist\RestfulApi\ResourceFilter\Objects\FilteringRules;
use Nvmcommunity\Alchemist\RestfulApi\ResourceFilter\Objects\FilteringOptions;

$restfulApi = new AlchemistRestfulApi([
    // The filtering are passed in from the request input.
    // Use a colon `:` to separate filtering and operator.
    'filtering' => [
        'order_date:lte' => '2023-02-26',
        'product_name:contains' => 'clothes hanger'
    ]
]);

$resourceFilter = $restfulApi->resourceFilter()
    // Defining options for your API
    ->defineFilteringOptions(new FilteringOptions([
        // Your API client needs to pass order_date filtering with any operation in order to pass the validator
        '    // Your API allows filtering by is_best_sales with the operations "eq" and the data of the filtering must
        // be an integer type with value of: `0` (represent for false) or `1` (represent for true)
        FilteringRules::Boolean('is_best_sales', ['eq']),
    ]);

// Support for setting a default filtering in case your API client does not pass data to a specific filtering.
$resourceFilter->addFilteringIfNotExists('is_best_sales', 'eq', 1);

// Validate your API client filtering, the same concept with field selector above
if (! $restfulApi->validate($errorBag)->passes()) {
    // var_dump(json_encode($errorBag->getErrors()));

    echo "validate failed"; die();
}

// And finally, what you will receive is a list of filtering objects, and everything has been carefully checked.

// Combine with the use of an ORM/Query Builder

$conditions = array_map(static fn($filteringObj) => $filteringObj->flatArray(), $resourceFilter->filtering());

$result = ExampleOrderQueryBuilder::where($conditions)->get();

// For other purposes, use `$resourceFilter->filtering()` to obtain a complete map list of filtering object.

var_dump($resourceFilter->filtering());

// `String` type is a special type that allows you to filter the data based on the string value.
FilteringRules::String(string $filtering, array $supportedOperators)

// `Integer` type is a special type that allows you to filter the data based on the integer value.
FilteringRules::Integer(string $filtering, array $supportedOperators)

// `Number` type is a special type that allows you to filter the data based on the numeric value.
FilteringRules::Number(string $filtering, array $supportedOperators)

// `Date` type allow you to define the date format that your API client can use to filter the data, default format: 'Y-m-d'
FilteringRules::Date(string $filtering, array $supportedOperators, array $formats = ['Y-m-d'])

// // `Datetime` type allow you to define the date and time format that your API client can use to filter the data, default format: 'Y-m-d H:i:s'
FilteringRules::Datetime(string $filtering, array $supportedOperators, array $formats = ['Y-m-d H:i:s'])

// `Enum` type is a special type that allows you to define a list of values that your API client can use to filter the data.
FilteringRules::Enum(string $filtering, array $supportedOperators, array $enums)

// `Boolean` type is a special type that allows you to define the boolean value that your API client can use to filter the data.
FilteringRules::Boolean(string $filtering, array $supportedOperators = [])

$restfulApi = new AlchemistRestfulApi([
    // The limit and offset are passed in from the request input.
    'limit' => 10,
    'offset' => 0,
]);

$resourceOffsetPaginator = $restfulApi->resourceOffsetPaginator()
    // Define default limit for resource
    ->defineDefaultLimit(10)

     // Define max limit for resource (set max limit to `0` or not define it will disable max limit)
    ->defineMaxLimit(1000);


// Validate your API client pagination parameters (limit, offset), Check if the offset value passed in is negative
// or not, and whether the limit parameter passed in exceeds the max limit (if max limit defined).
if (! $resourceOffsetPaginator->validate($notification)->passes()) {
    // var_dump(json_encode($errorBag->getErrors()));

    echo "validate failed"; die();
}

// Receive an object containing parameters for offset, limit, and max limit.
$offsetPaginate = $resourceOffsetPaginator->offsetPaginate();

// Combine with the use of an ORM/Query Builder
$result = ExampleOrderQueryBuilder::limit($offsetPaginate->getLimit())->offset($offsetPaginate->getOffset())->get();

$restfulApi = new AlchemistRestfulApi([
    // The sort and direction are passed in from the request input.
    'sort' => 'id',
    'direction' => 'desc',
]);

$resourceSort = $restfulApi->resourceSort()
    // define default sort field
    ->defineDefaultSort('id')
    
    // define default sort direction
    ->defineDefaultDirection('desc')

    // define list of field that client able to sort
    ->defineSortableFields(['id', 'created_at']);

// Validate your API client sort parameters (sort, direction), Check if the sort field passed in is in the list of
// sortable fields, and whether the direction parameter passed in is valid.
if (! $restfulApi->validate($errorBag)->passes()) {
    // var_dump(json_encode($errorBag->getErrors()));

    echo "validate failed"; die();
}

$sort = $resourceSort->sort();

// Combine with the use of an ORM/Query Builder

if (! empty($sort->getSortField())) {
    ExampleOrderQueryBuilder::orderBy($sort->getSortField(), $sort->getDirection());
}

$restfulApi = new AlchemistRestfulApi([
    // The search are passed in from the request input.
    'search' => 'clothes hanger',
]);

$resourceSearch = $restfulApi->resourceSearch()
    // define the search criteria
    ->defineSearchCondition('product_name');
    
$search = $resourceSearch->search();

// Combine with the use of an ORM/Query Builder
ExampleOrderQueryBuilder::where($search->getSearchCondition(), 'like', "%{$search->getSearchValue()}%");