PHP code example of bambamboole / laravel-openapi

1. Go to this page and download the library: Download bambamboole/laravel-openapi 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/ */

    

bambamboole / laravel-openapi example snippets


#[OA\Schema(
    schema: 'SalesOrder',
    property: 'id', type: 'integer'),
        new OA\Property(property: 'status', ref: SalesOrderStatus::class),
        new OA\Property(property: 'customer', anyOf: [
            new OA\Schema(ref: CustomerResource::class),
            new OA\Schema(properties: [new OA\Property(property: 'id', type: 'integer')], type: 'object'),
        ]
        ),
        new OA\Property(property: 'positions', type: 'array', items: new OA\Items(ref: SalesOrderPositionResource::class), nullable: true),
        new OA\Property(property: 'created_at', type: 'datetime'),
        new OA\Property(property: 'updated_at', type: 'datetime'),
    ],
    type: 'object',
    additionalProperties: false,
)]
class SalesOrderResource extends JsonResource
{
    /** @var SalesOrder */
    public $resource;

    public function toArray($request): array
    {
        return [
            'id' => $this->resource->id,
            'status' => $this->resource->status,
            'customer' => $this->whenLoaded('customer', fn () => new CustomerResource($this->resource->customer), ['id' => $this->resource->customer_id]),
            'positions' => $this->whenLoaded('positions', fn () => SalesOrderPositionResource::collection($this->resource->positions)),
            'created_at' => $this->resource->created_at->format(DATE_ATOM),
            'updated_at' => $this->resource->updated_at->format(DATE_ATOM),
        ];
    }
}

    #[ListEndpoint(
        path: '/api/v1/sales-orders',
        resource: SalesOrderResource::class,
        description: 'Paginated list of sales orders',
         /// ...
            new QuerySort(['created_at', 'updated_at']),
        ],
        tags: ['SalesOrder'],
    )]
    public function index(): AnonymousResourceCollection
    {
        $salesOrders = QueryBuilder::for(SalesOrder::class)
            ->withCount('positions')
            ->defaultSort('-created_at')
            ->allowedFilters([
                QueryFilter::identifier(),
                QueryFilter::string('documentNumber'),
                QueryFilter::date('documentDate', 'datum'),
                new AllowedFilter('positions.count', new RelationCountFilter(),'positions'),
                // ...
            ])
            ->allowedSorts([
                AllowedSort::field('created_at'),
                AllowedSort::field('updated_at'),
            ])
            ->allowedIncludes([
                'customer',
                'positions',
            ])
            ->apiPaginate();

        return SalesOrderResource::collection($salesOrders);
    }
  
    #[GetEndpoint(
        path: '/api/v1/sales-orders/{id}',
        resource: SalesOrderResource::class,
        description: 'View a single sales order',
        tags: ['SalesOrder'],
              'positions',
            ])
            ->findOrFail($id);

        return new SalesOrderResource($salesOrder);
    }

#[OA\Schema(
    schema: 'CreateSalesOrderRequest',
    oject', type: 'object',  properties: [new OA\Property(property: 'id', type: 'integer')]),
        new OA\Property(property: 'tags', type: 'array', items: new OA\Items(type: 'string')),
        new OA\Property(property: 'positions', type: 'array', items: new OA\Items(
            s CreateSalesOrderRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'project.id' => [':0,2'],
            'positions.*.price.currency' => ['

    #[PostEndpoint(
        path: '/api/v1/sales-orders',
        request: CreateSalesOrderRequest::class,
        resource: SalesOrderResource::class,
        description: 'Create a new sales order',
        tags: ['SalesOrder'],
        successStatus: '201',
    )]
    public function create(CreateSalesOrderRequest $request): SalesOrderResource
    {
        $salesOrder = SalesOrder::create([
            // ...
        ]);

        return new SalesOrderResource($salesOrder);
    }



    #[PatchEndpoint(
        path: '/api/v1/sales-orders/{id}',
        request: UpdateSalesOrderRequest::class,
        resource: SalesOrderResource::class,
        description: 'Update an existing sales order',
        tags: ['SalesOrder'],
    )]
    public function update(UpdateSalesOrderRequest $request, int $id): SalesOrderResource
    {
        $salesOrder = SalesOrder::with('positions')->findOrFail($id);

        // Handle update logic here, e.g. updating positions, customer, etc.

        return new SalesOrderResource($salesOrder);
    }

    #[DeleteEndpoint(
        path: '/api/v1/sales-orders/{id}',
        description: 'Delete a sales order',
        tags: ['SalesOrder'],
        validates: ['status' => 'Only pending sales orders can be deleted.'],
    )]
    public function delete(int $id): Response
    {
        $salesOrder = SalesOrder::findOrFail($id);

        if ($salesOrder->status !== SalesOrderStatus::PENDING) {
            throw ValidationException::withMessages([
                'status' => 'Only pending sales orders can be deleted. Current status: '.$salesOrder->status->value,
            ]);
        }

        $salesOrder->positions()->delete();
        $salesOrder->delete();

        return response()->noContent();
    }

return [
    'docs' => [
        'enabled' => env('APP_ENV') !== 'production',
        'prefix' => 'api-docs',
    ],
    'schemas' => [
        'default' => [
            'oas_version' => '3.1.0',
            'ruleset' => null,
            'folders' => [base_path('app')],
            'output' => base_path('openapi.yml'),
            'name' => 'My API',
            'version' => '1.0.0',
            'description' => 'Developer API',
            'contact' => [
                'name' => 'API Support',
                'url' => env('APP_URL', 'https://.example.com'),
                'email' => env('MAIL_FROM_ADDRESS', '[email protected]'),
            ],
            'servers' => [
                [
                    'url' => env('APP_URL', 'https://.example.com'),
                    'description' => 'Your API environment',
                ],
            ],
        ],
    ],
    'merge' => [
        'schemas' => ['default'],
    ],
];

'schemas' => [
    'v1' => [
        'folders' => [base_path('app/Http/Controllers/Api/V1')],
        'output' => base_path('openapi-v1.yml'),
        // other settings...
    ],
    'v2' => [
        'folders' => [base_path('app/Http/Controllers/Api/V2')],
        'output' => base_path('openapi-v2.yml'),
        // other settings...
    ],
],

'merge' => [
    'schemas' => ['default', 'v2'], // List the schema keys you want to merge
    'files' => [base_path('extra_spec.json')], // (Optional) Additional files to merge
    'output' => base_path('openapi_merged.yml'), // (Optional) Output file path
],

'schemas' => [
    'v1' => [
        'folders' => [base_path('app/Http/Controllers/Api/V1')],
        'output' => base_path('openapi-v1.yml'),
    ],
    'v2' => [
        'folders' => [base_path('app/Http/Controllers/Api/V2')],
        'output' => base_path('openapi-v2.yml'),
    ],
],

'merge' => [
    'schemas' => ['v1', 'v2'],
    'files' => [base_path('extra_spec.json')], // Optional additional files from other sources
    'output' => base_path('openapi_merged.yml'),
],

'docs' => [
    'enabled' => env('APP_ENV') !== 'production', // Enable or disable the web interface
    'prefix' => 'api-docs', // URL prefix for the web interface
    'middlewares' => [], // Additional middlewares to apply
],



namespace App\OpenApi\Filters;

use Bambamboole\LaravelOpenApi\Attributes\FilterProperty;
use Bambamboole\LaravelOpenApi\Attributes\FilterPropertyCollection;
use Bambamboole\LaravelOpenApi\Enum\FilterType;

#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
class UserFilters implements FilterPropertyCollection
{
    public function getFilterProperties(): array
    {
        return [
            new FilterProperty(
                name: 'name',
                description: 'Filter users by name',
                type: 'string',
                filterType: FilterType::PARTIAL
            ),
            new FilterProperty(
                name: 'email',
                description: 'Filter users by email',
                type: 'string',
                filterType: FilterType::EXACT
            ),
            new FilterProperty(
                name: 'created_at',
                description: 'Filter users by creation date',
                type: 'string',
                filterType: FilterType::OPERATOR,
                operators: ['eq', 'gt', 'lt', 'gte', 'lte']
            ),
        ];
    }
}

#[ListEndpoint(
    path: '/api/v1/users',
    resource: UserResource::class,
    description: 'Paginated list of users',
    parameters: [
        new UserFilters(),
        new QuerySort(['created_at', 'updated_at']),
    ],
    tags: ['User'],
)]
public function index(): AnonymousResourceCollection
{
    $users = QueryBuilder::for(User::class)
        ->defaultSort('-created_at')
        ->allowedFilters([
            QueryFilter::string('name'),
            QueryFilter::string('email'),
            QueryFilter::date('created_at'),
        ])
        ->allowedSorts([
            AllowedSort::field('created_at'),
            AllowedSort::field('updated_at'),
        ])
        ->apiPaginate();

    return UserResource::collection($users);
}
bash
php artisan openapi:generate
bash
php artisan vendor:publish --provider="Bambamboole\LaravelOpenApi\OpenApiServiceProvider"
bash
php artisan openapi:generate v1
bash
php artisan openapi:merge