feat: SearchManga endpoint + tests
This commit is contained in:
parent
6667cc224b
commit
ae0eac3197
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Manga\Infrastructure\ApiPlatform\Dto;
|
||||
|
||||
readonly class MangaSearchCollection
|
||||
{
|
||||
public function __construct(
|
||||
/** @var MangaSearchItem[] */
|
||||
public array $items
|
||||
) {}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Manga\Infrastructure\ApiPlatform\Dto;
|
||||
|
||||
use ApiPlatform\Metadata\ApiProperty;
|
||||
|
||||
readonly class MangaSearchItem
|
||||
{
|
||||
public function __construct(
|
||||
#[ApiProperty(identifier: true)]
|
||||
public string $externalId,
|
||||
public string $title,
|
||||
public string $slug,
|
||||
public string $description,
|
||||
public string $author,
|
||||
public int $publicationYear,
|
||||
public array $genres,
|
||||
public string $status,
|
||||
public ?string $imageUrl,
|
||||
public ?float $rating
|
||||
) {}
|
||||
}
|
||||
@@ -13,7 +13,51 @@ use App\Domain\Manga\Infrastructure\ApiPlatform\State\Provider\GetMangaChaptersS
|
||||
new Get(
|
||||
uriTemplate: '/mangas/{id}/chapters',
|
||||
provider: GetMangaChaptersStateProvider::class,
|
||||
output: ChapterCollection::class
|
||||
output: ChapterCollection::class,
|
||||
openapiContext: [
|
||||
'parameters' => [
|
||||
[
|
||||
'name' => 'id',
|
||||
'in' => 'path',
|
||||
'required' => true,
|
||||
'schema' => [
|
||||
'type' => 'string'
|
||||
],
|
||||
'description' => 'The manga identifier'
|
||||
],
|
||||
[
|
||||
'name' => 'page',
|
||||
'in' => 'query',
|
||||
'required' => false,
|
||||
'schema' => [
|
||||
'type' => 'integer',
|
||||
'default' => 1
|
||||
],
|
||||
'description' => 'The page number'
|
||||
],
|
||||
[
|
||||
'name' => 'limit',
|
||||
'in' => 'query',
|
||||
'required' => false,
|
||||
'schema' => [
|
||||
'type' => 'integer',
|
||||
'default' => 20
|
||||
],
|
||||
'description' => 'Number of items per page'
|
||||
],
|
||||
[
|
||||
'name' => 'sortOrder',
|
||||
'in' => 'query',
|
||||
'required' => false,
|
||||
'schema' => [
|
||||
'type' => 'string',
|
||||
'enum' => ['asc', 'desc'],
|
||||
'default' => 'desc'
|
||||
],
|
||||
'description' => 'Sort order for chapters'
|
||||
]
|
||||
]
|
||||
]
|
||||
)
|
||||
]
|
||||
)]
|
||||
|
||||
@@ -13,7 +13,20 @@ use App\Domain\Manga\Infrastructure\ApiPlatform\State\Provider\GetMangaStateProv
|
||||
new Get(
|
||||
uriTemplate: '/mangas/{id}',
|
||||
provider: GetMangaStateProvider::class,
|
||||
output: MangaDetail::class
|
||||
output: MangaDetail::class,
|
||||
openapiContext: [
|
||||
'parameters' => [
|
||||
[
|
||||
'name' => 'id',
|
||||
'in' => 'path',
|
||||
'required' => true,
|
||||
'schema' => [
|
||||
'type' => 'string'
|
||||
],
|
||||
'description' => 'The manga identifier'
|
||||
]
|
||||
]
|
||||
]
|
||||
)
|
||||
]
|
||||
)]
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Manga\Infrastructure\ApiPlatform\Resource;
|
||||
|
||||
use ApiPlatform\Metadata\ApiResource;
|
||||
use ApiPlatform\Metadata\Get;
|
||||
use App\Domain\Manga\Infrastructure\ApiPlatform\Dto\MangaSearchCollection;
|
||||
use App\Domain\Manga\Infrastructure\ApiPlatform\State\Provider\SearchMangaStateProvider;
|
||||
|
||||
#[ApiResource(
|
||||
shortName: 'MangaSearch',
|
||||
operations: [
|
||||
new Get(
|
||||
uriTemplate: '/mangas-search',
|
||||
openapiContext: [
|
||||
'parameters' => [
|
||||
[
|
||||
'name' => 'title',
|
||||
'in' => 'query',
|
||||
'required' => true,
|
||||
'schema' => [
|
||||
'type' => 'string'
|
||||
],
|
||||
'description' => 'The title to search for'
|
||||
]
|
||||
]
|
||||
],
|
||||
output: MangaSearchCollection::class,
|
||||
provider: SearchMangaStateProvider::class
|
||||
)
|
||||
]
|
||||
)]
|
||||
class MangaSearchResource
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Manga\Infrastructure\ApiPlatform\State\Provider;
|
||||
|
||||
use ApiPlatform\Metadata\Operation;
|
||||
use ApiPlatform\State\ProviderInterface;
|
||||
use App\Domain\Manga\Application\Query\SearchManga;
|
||||
use App\Domain\Manga\Application\QueryHandler\SearchMangaHandler;
|
||||
use App\Domain\Manga\Infrastructure\ApiPlatform\Dto\MangaSearchCollection;
|
||||
use App\Domain\Manga\Infrastructure\ApiPlatform\Dto\MangaSearchItem;
|
||||
|
||||
readonly class SearchMangaStateProvider implements ProviderInterface
|
||||
{
|
||||
public function __construct(
|
||||
private SearchMangaHandler $handler
|
||||
) {}
|
||||
|
||||
public function provide(Operation $operation, array $uriVariables = [], array $context = []): MangaSearchCollection
|
||||
{
|
||||
$title = $context['filters']['title'] ?? '';
|
||||
|
||||
$query = new SearchManga($title);
|
||||
$response = $this->handler->handle($query);
|
||||
|
||||
return new MangaSearchCollection(
|
||||
items: array_map(
|
||||
fn ($item) => new MangaSearchItem(
|
||||
externalId: $item->externalId,
|
||||
title: $item->title,
|
||||
slug: $item->slug,
|
||||
description: $item->description,
|
||||
author: $item->author,
|
||||
publicationYear: $item->publicationYear,
|
||||
genres: $item->genres,
|
||||
status: $item->status,
|
||||
imageUrl: $item->imageUrl,
|
||||
rating: $item->rating
|
||||
),
|
||||
$response->items
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user