Skip to content

Commit

Permalink
Support #[ResponseField] on API resources
Browse files Browse the repository at this point in the history
  • Loading branch information
shalvah committed Nov 10, 2022
1 parent 2f5e6d3 commit 66492aa
Show file tree
Hide file tree
Showing 10 changed files with 61 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@
*/
class GetFromBodyParamAttribute extends GetParamsFromAttributeStrategy
{
protected array $attributeNames = [BodyParam::class];
protected static array $attributeNames = [BodyParam::class];
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
*/
class GetFromHeaderAttribute extends PhpAttributeStrategy
{
protected array $attributeNames = [Header::class];
protected static array $attributeNames = [Header::class];

protected function extractFromAttributes(
array $attributesOnMethod, array $attributesOnController,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class GetFromMetadataAttributes extends PhpAttributeStrategy
{
use ParamHelpers;

protected array $attributeNames = [
protected static array $attributeNames = [
Group::class,
Subgroup::class,
Endpoint::class,
Expand Down
6 changes: 3 additions & 3 deletions src/Extracting/Strategies/PhpAttributeStrategy.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ abstract class PhpAttributeStrategy extends Strategy
/**
* @var string[]
*/
protected array $attributeNames;
protected static array $attributeNames;

public function __invoke(ExtractedEndpointData $endpointData, array $routeRules = []): array
{
Expand All @@ -37,12 +37,12 @@ public function __invoke(ExtractedEndpointData $endpointData, array $routeRules
*/
protected function getAttributes(ReflectionFunctionAbstract $method, ?ReflectionClass $class = null): array
{
$attributesOnMethod = collect($this->attributeNames)
$attributesOnMethod = collect(static::$attributeNames)
->flatMap(fn(string $name) => $method->getAttributes($name))
->map(fn(ReflectionAttribute $a) => $a->newInstance())->all();

if ($class) {
$attributesOnController = collect($this->attributeNames)
$attributesOnController = collect(static::$attributeNames)
->flatMap(fn(string $name) => $class->getAttributes($name))
->map(fn(ReflectionAttribute $a) => $a->newInstance())->all();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@
*/
class GetFromQueryParamAttribute extends GetParamsFromAttributeStrategy
{
protected array $attributeNames = [QueryParam::class];
protected static array $attributeNames = [QueryParam::class];
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,39 @@

use Knuckles\Camel\Extraction\ExtractedEndpointData;
use Knuckles\Scribe\Attributes\ResponseField;
use Knuckles\Scribe\Attributes\ResponseFromApiResource;
use Knuckles\Scribe\Extracting\Shared\ResponseFieldTools;
use Knuckles\Scribe\Extracting\Strategies\PhpAttributeStrategy;
use Knuckles\Scribe\Tools\Utils as u;
use ReflectionAttribute;

/**
* @extends PhpAttributeStrategy<ResponseField>
*/
class GetFromResponseFieldAttribute extends PhpAttributeStrategy
{
protected array $attributeNames = [ResponseField::class];
protected static array $attributeNames = [ResponseField::class];

protected function extractFromAttributes(
array $attributesOnMethod, array $attributesOnController,
ExtractedEndpointData $endpointData
): ?array
{
return collect([...$attributesOnController, ...$attributesOnMethod])
$attributesOnApiResourceMethods = [];
$apiResourceAttributes = $endpointData->method->getAttributes(ResponseFromApiResource::class);

if (!empty($apiResourceAttributes)) {
$attributesOnApiResourceMethods = collect($apiResourceAttributes)
->flatMap(function (ReflectionAttribute $attribute) {
$className = $attribute->newInstance()->name;
$method = u::getReflectedRouteMethod([$className, 'toArray']);
return collect($method->getAttributes(ResponseField::class))
->map(fn (ReflectionAttribute $attr) => $attr->newInstance());
});
}


return collect([...$attributesOnController, ...$attributesOnMethod, ...$attributesOnApiResourceMethods])
->mapWithKeys(function ($attributeInstance) use ($endpointData) {
$data = $attributeInstance->toArray();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class UseResponseAttributes extends PhpAttributeStrategy
{
use ParamHelpers, DatabaseTransactionHelpers, InstantiatesExampleModels;

protected array $attributeNames = [
protected static array $attributeNames = [
Response::class,
ResponseFromFile::class,
ResponseFromApiResource::class,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@
*/
class GetFromUrlParamAttribute extends GetParamsFromAttributeStrategy
{
protected array $attributeNames = [UrlParam::class];
protected static array $attributeNames = [UrlParam::class];
}
3 changes: 3 additions & 0 deletions tests/Fixtures/TestPetApiResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Knuckles\Scribe\Tests\Fixtures;

use Illuminate\Http\Resources\Json\JsonResource;
use Knuckles\Scribe\Attributes\ResponseField;

class TestPetApiResource extends JsonResource
{
Expand All @@ -13,6 +14,8 @@ class TestPetApiResource extends JsonResource
*
* @return array
*/
#[ResponseField('id', description: 'The id of the pet.')]
#[ResponseField('species', 'string', 'The breed')]
public function toArray($request)
{
$result = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
use Knuckles\Camel\Extraction\ExtractedEndpointData;
use Knuckles\Camel\Extraction\ResponseCollection;
use Knuckles\Scribe\Attributes\ResponseField;
use Knuckles\Scribe\Attributes\ResponseFromApiResource;
use Knuckles\Scribe\Extracting\Strategies\ResponseFields\GetFromResponseFieldAttribute;
use Knuckles\Scribe\Tests\Fixtures\TestPet;
use Knuckles\Scribe\Tests\Fixtures\TestPetApiResource;
use Knuckles\Scribe\Tools\DocumentationConfig;
use PHPUnit\Framework\TestCase;
use DMS\PHPUnitExtensions\ArraySubset\ArraySubsetAsserts;
Expand Down Expand Up @@ -51,6 +54,28 @@ public function can_fetch_from_responsefield_attribute()
], $results);
}

/** @test */
public function can_read_from_toArray_on_API_resources()
{
$endpoint = $this->endpoint(function (ExtractedEndpointData $e) {
$e->controller = new ReflectionClass(ResponseFieldAttributeTestController::class);
$e->method = $e->controller->getMethod('methodWithApiResourceResponse');
$e->responses = new ResponseCollection([]);
});
$results = $this->fetch($endpoint);

$this->assertArraySubset([
'id' => [
'type' => '',
'description' => 'The id of the pet.',
],
'species' => [
'type' => 'string',
'description' => 'The breed',
],
], $results);
}

protected function fetch($endpoint): array
{
$strategy = new GetFromResponseFieldAttribute(new DocumentationConfig([]));
Expand All @@ -76,4 +101,9 @@ class ResponseFieldAttributeTestController
public function methodWithAttributes()
{
}

#[ResponseFromApiResource(TestPetApiResource::class, TestPet::class)]
public function methodWithApiResourceResponse()
{
}
}

0 comments on commit 66492aa

Please sign in to comment.