Digging Deeper

Instructions

Instructions are a way to provide customization to your search requests fully depending on your needs. They give you full access to the query.

Overview

Instructions can be generated by using the rest:instruction Artisan command. By default, all instructions are placed in your App\Rest\Instructions directory.

php artisan rest:instruction OddEvenIdInstruction

You are now ready to configure your instruction:

namespace App\Rest\Instructions;

use Illuminate\Database\Eloquent\Model;
use Lomkit\Rest\Instructions\Instruction;
use Lomkit\Rest\Http\Requests\RestRequest;

class OddEvenIdInstruction extends Instruction
{
    /**
     * Perform the instruction on the given query.
     *
     * @param array $fields
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @return void
     */
    public function handle(array $fields, \Illuminate\Database\Eloquent\Builder $query)
    {
       $number = match ($fields['type'] ?? 'even') {
           'odd' => 1,
           default => 0,
       };
        
        return $query
            ->whereRaw('MOD(id, 2) = '.$number);
    }

    /**
     * The instruction fields.
     *
     * @param  \Lomkit\Rest\Http\Requests\RestRequest $request
     * @return array
     */
    public function fields(\Lomkit\Rest\Http\Requests\RestRequest $request): array
    {
        return [
            'type' => [
                'string',
                'in:odd,even'
            ]
        ];
    }
}

In the handle method, you have the flexibility to interact with the current search query as you see fit.

You can access the resource that launched the instruction by using $this->resource at any moment.

Register an instruction

To register an instruction, you simply need to specify it in your resource:

use App\Rest\Instructions\OddEvenIdInstruction;

class UserResource extends Resource
{
    /**
     * The instructions that should be linked
     * @param RestRequest $request
     * @return array
     */
    public function instructions(RestRequest $request): array {
        return [
            OddEvenIdInstruction::make()
        ];
    }
}

Authorizations

In case you don't want to expose your instructions to all users, you simply need to condition this method:

use App\Rest\Instructions\OddEvenIdInstruction;

class UserResource extends Resource
{
    /**
     * The instructions that should be linked
     * @param RestRequest $request
     * @return array
     */
    public function instructions(RestRequest $request): array {
        $instructions = [];
        
        if ($request->user()->isAdministrator()) {
            array_push($instructions, OddEvenIdInstruction::make())
        }
    
        return $instructions;
    }
}

Fields

Sometimes, you want to directly collect data from your frontend users. This is what fields are made for. You need to define them in your instruction first:

namespace App\Rest\Instructions;

use Illuminate\Database\Eloquent\Model;
use Lomkit\Rest\Instructions\Instruction;
use Lomkit\Rest\Http\Requests\RestRequest;

class OddEvenIdInstruction extends Instruction
{
     /**
     * The instruction fields.
     *
     * @param  \Lomkit\Rest\Http\Requests\RestRequest $request
     * @return array
     */
    public function fields(\Lomkit\Rest\Http\Requests\RestRequest $request)
    {
        return [
            'type' => [
                'string',
                'in:odd,even'
            ]
        ];
    }
}

In the returned array, the key should correspond to the field name provided in the call, while the value should represent the desired set of validations for that field. Laravel Rest API automatically validates all fields based on your defined validation rules.

You get those fields in the $field variable in your handle method.

Meta

Because your instructions are exposed to frontend users, they do receive certain information about them, such as uriKey, name and fields. However, you are also welcome to provide your own data.

You can achieve this by invoking withMeta within your instruction's constructor:

class OddEvenIdInstruction extends Instruction
{
    public function __construct()
    {
        $this->withMeta([
            'color' => '#FFFFFF'
        ]);
    }
}

Alternatively, you can call it during the instruction registration if you wish to define distinct meta information based on the resource:

use App\Rest\Instructions\OddEvenIdInstruction;

class UserResource extends Resource
{
    /**
     * The instructions that should be linked
     * @param RestRequest $request
     * @return array
     */
    public function instructions(RestRequest $request): array {
        return [
            OddEvenIdInstruction::make()
                ->withMeta(['color' => '#FFFFFF'])
        ];
    }
}

Copyright © 2024