The idea is to add Swagger-PHP annotations or attributes next to the relevant PHP code in your application. These will contain the details about your API and swagger-php will convert those into machine-readable OpenAPI documentation.
In the following codes, we have exemplified the most commonly used Swagger-PHP annotations in an Olobase backend application, one by one.
src/App/Handler/CreateHandler.php
<?php declare(strict_types=1);
namespace App\Handler\Companies;
use App\Model\CompanyModel;
use App\Schema\Companies\CompanySave;
use App\Filter\Companies\SaveFilter;
use Olobase\Mezzio\DataManagerInterface;
use Olobase\Mezzio\Error\ErrorWrapperInterface as Error;
use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
class CreateHandler implements RequestHandlerInterface
{
public function __construct(
private CompanyModel $companySaveModel,
private DataManagerInterface $dataManager,
private SaveFilter $filter,
private Error $error,
)
{
$this->companySaveModel = $companySaveModel;
$this->dataManager = $dataManager;
$this->error = $error;
$this->filter = $filter;
}
/**
* @OA\Post(
* path="/companies/create",
* tags={"Companies"},
* summary="Create a new company",
* operationId="companies_create",
*
* @OA\RequestBody(
* description="Create new Company",
* @OA\JsonContent(ref="#/components/schemas/CompanySave"),
* ),
* @OA\Response(
* response=200,
* description="Successful operation",
* ),
* @OA\Response(
* response=400,
* description="Bad request, returns to validation errors"
* )
*)
**/
public function handle(ServerRequestInterface $request): ResponseInterface
{
$this->filter->setInputData($request->getParsedBody());
$data = array();
$response = array();
if ($this->filter->isValid()) {
$this->dataManager->setInputFilter($this->filter);
$data = $this->dataManager->getSaveData(CompanySave::class, 'companies');
$this->companySaveModel->create($data);
} else {
return new JsonResponse($this->error->getMessages($this->filter), 400);
}
return new JsonResponse($response);
}
}
src/App/Handler/DeleteHandler.php
<?php declare(strict_types=1);
namespace App\Handler\Companies;
use App\Model\CompanyModel;
use App\Filter\Companies\DeleteFilter;
use Olobase\Mezzio\Error\ErrorWrapperInterface as Error;
use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
class DeleteHandler implements RequestHandlerInterface
{
public function __construct(
private CompanyModel $companyModel,
private DeleteFilter $filter,
private Error $error,
)
{
$this->companyModel = $companyModel;
$this->filter = $filter;
$this->error = $error;
}
/**
* @OA\Delete(
* path="/companies/delete/{companyId}",
* tags={"Companies"},
* summary="Delete company",
* operationId="companyies_delete",
*
* @OA\Parameter(
* in="path",
* name="companyId",
* required=true,
* description="Company uuid",
* @OA\Schema(
* type="string",
* format="uuid",
* ),
* ),
* @OA\Response(
* response=200,
* description="Successful operation",
* )
*)
**/
public function handle(ServerRequestInterface $request): ResponseInterface
{
$this->filter->setInputData($request->getQueryParams());
if ($this->filter->isValid()) {
$this->companyModel->delete(
$this->filter->getValue('id')
);
} else {
return new JsonResponse($this->error->getMessages($this->filter), 400);
}
return new JsonResponse([]);
}
}
src/App/Handler/FindAllHandler.php
<?php declare(strict_types=1);
namespace App\Handler\Companies;
use App\Model\CompanyModel;
use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
class FindAllHandler implements RequestHandlerInterface
{
public function __construct(CompanyModel $companyModel)
{
$this->companyModel = $companyModel;
}
/**
* @OA\Get(
* path="/companies/findAll",
* tags={"Companies"},
* summary="Find all companies",
* operationId="companies_findAll",
*
* @OA\Response(
* response=200,
* description="Successful operation",
* @OA\JsonContent(ref="#/components/schemas/CommonFindAll"),
* ),
* @OA\Response(
* response=404,
* description="No result found"
* )
*)
**/
public function handle(ServerRequestInterface $request): ResponseInterface
{
$data = $this->companyModel->findCompanies();
return new JsonResponse([
'data' => $data,
]);
}
}
src/App/Handler/FindAllByPagingHandler.php
<?php declare(strict_types=1);
namespace App\Handler\Companies;
use App\Model\CompanyModel;
use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
class FindAllByPagingHandler implements RequestHandlerInterface
{
public function __construct(CompanyModel $companyModel)
{
$this->companyModel = $companyModel;
}
/**
* @OA\Get(
* path="/companies/findAllByPaging",
* tags={"Companies"},
* summary="Find all companies by pagination",
* operationId="companies_findAllByPaging",
*
* @OA\Parameter(
* name="q",
* in="query",
* required=false,
* description="Search string",
* @OA\Schema(
* type="string",
* ),
* ),
* @OA\Parameter(
* name="_page",
* in="query",
* required=false,
* description="Page number",
* @OA\Schema(
* type="integer",
* ),
* ),
* @OA\Parameter(
* name="_perPage",
* in="query",
* required=false,
* description="Per page",
* @OA\Schema(
* type="integer",
* ),
* ),
* @OA\Parameter(
* name="_sort",
* in="query",
* required=false,
* description="Order items",
* @OA\Schema(
* type="array",
* @OA\Items()
* ),
* ),
* @OA\Response(
* response=200,
* description="Successful operation",
* @OA\JsonContent(ref="#/components/schemas/CompaniesFindAllByPaging"),
* ),
* @OA\Response(
* response=404,
* description="No result found"
* )
*)
**/
public function handle(ServerRequestInterface $request): ResponseInterface
{
$get = $request->getQueryParams();
$page = empty($get['_page']) ? 1 : (int)$get['_page'];
$perPage = empty($get['_perPage']) ? 5 : (int)$get['_perPage'];
// https://docs.laminas.dev/tutorials/pagination/
$paginator = $this->companyModel->findAllByPaging($get);
$page = ($page < 1) ? 1 : $page;
$paginator->setCurrentPageNumber($page);
$paginator->setItemCountPerPage($perPage);
return new JsonResponse([
'page' => $paginator->getCurrentPageNumber(),
'perPage' => $paginator->getItemCountPerPage(),
'totalPages' => $paginator->count(),
'totalItems' => $paginator->getTotalItemCount(),
'data' => paginatorJsonDecode($paginator->getCurrentItems()),
]);
}
}
src/App/Handler/FindOneByIdHandler.php
<?php declare(strict_types=1);
namespace App\Handler\Companies;
use App\Model\CompanyModel;
use Olobase\Mezzio\DataManagerInterface;
use App\Schema\Companies\CompaniesFindOneById;
use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
class FindOneByIdHandler implements RequestHandlerInterface
{
public function __construct(
private CompanyModel $companyModel,
private DataManagerInterface $dataManager
)
{
$this->companyModel = $companyModel;
$this->dataManager = $dataManager;
}
/**
* @OA\Get(
* path="/companies/findOneById/{companyId}",
* tags={"Companies"},
* summary="Find company data",
* operationId="companies_findOneById",
*
* @OA\Parameter(
* name="companyId",
* in="path",
* required=true,
* @OA\Schema(
* type="string",
* ),
* ),
* @OA\Response(
* response=200,
* description="Successful operation",
* @OA\JsonContent(ref="#/components/schemas/CompaniesFindOneById"),
* ),
*)
**/
public function handle(ServerRequestInterface $request): ResponseInterface
{
$row = $this->companyModel->findOneById($request->getAttribute("companyId"));
if ($row) {
$data = $this->dataManager->getViewData(CompaniesFindOneById::class, $row);
return new JsonResponse($data);
}
return new JsonResponse([], 404);
}
}