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();
}
'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);
}