diff --git a/src/Http/Serializer/DeserializeParameterResolver.php b/src/Http/Serializer/DeserializeParameterResolver.php index b1281cb..8f276ff 100644 --- a/src/Http/Serializer/DeserializeParameterResolver.php +++ b/src/Http/Serializer/DeserializeParameterResolver.php @@ -7,6 +7,8 @@ use ReflectionFunctionAbstract; use ReflectionNamedType; use Slim\Exception\HttpBadRequestException; +use Symfony\Component\Serializer\Encoder\CsvEncoder; +use Symfony\Component\Serializer\Encoder\JsonEncoder; use Symfony\Component\Serializer\Exception\ExceptionInterface; use Symfony\Component\Serializer\Exception\MissingConstructorArgumentsException; use Symfony\Component\Serializer\Exception\NotNormalizableValueException; @@ -50,10 +52,16 @@ public function getParameters( PayloadSource::Get => $request->getQueryParams(), }; + $format = match ($attribute->source) { + PayloadSource::Post => JsonEncoder::FORMAT, + PayloadSource::Get => CsvEncoder::FORMAT, + }; + try { $resolvedParameters[$index] = $this->serializer->denormalize( $data, $parameterClass, + format: $format, context: $attribute->context, ); } catch (NotNormalizableValueException $e) { diff --git a/src/ServiceFactory/SlimServiceFactory.php b/src/ServiceFactory/SlimServiceFactory.php index 9c9e49e..566caee 100644 --- a/src/ServiceFactory/SlimServiceFactory.php +++ b/src/ServiceFactory/SlimServiceFactory.php @@ -19,6 +19,8 @@ use Slim\Middleware\ErrorMiddleware; use Slim\Psr7\Factory\ResponseFactory; use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor; +use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor; +use Symfony\Component\PropertyInfo\PropertyInfoExtractor; use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; @@ -38,7 +40,12 @@ public function __invoke(ServicesBuilder $builder): iterable { yield Serializer::class => static fn () => new Serializer([ new ArrayDenormalizer(), new ObjectNormalizer( - propertyTypeExtractor: new PhpDocExtractor(), + propertyTypeExtractor: new PropertyInfoExtractor( + typeExtractors: [ + new PhpDocExtractor(), + new ReflectionExtractor(), + ], + ), ), ]); yield DenormalizerInterface::class => get(Serializer::class); diff --git a/tests/Http/Serializer/BooleansInput.php b/tests/Http/Serializer/BooleansInput.php new file mode 100644 index 0000000..1021e40 --- /dev/null +++ b/tests/Http/Serializer/BooleansInput.php @@ -0,0 +1,12 @@ + 'cats'], ['name' => 'dogs'], ], + 'tag' => [ + 'name' => 'alpha', + ], ]; $get = [ 'page' => 3, + 'lists' => ['alpha', 'bravo'], + 'arrays' => ['charlie' => 'delta'], + 'booleans' => [ + 'true' => true, + 'false' => false, + 'one' => 1, + 'zero' => 0, + ], ]; $request = (new ServerRequestFactory()) ->createServerRequest('GET', '/?'.http_build_query($get)) ->withParsedBody($post); $response = $app->handle($request); + + $body = $response->getBody()->getContents(); + + self::assertSame( + 200, + $response->getStatusCode(), + $body, + ); + $actual = json_decode( - $response->getBody()->getContents(), + $body, associative: true, depth: 12, flags: JSON_THROW_ON_ERROR, diff --git a/tests/Http/Serializer/EchoController.php b/tests/Http/Serializer/EchoController.php index 5fa77f3..2f96d10 100644 --- a/tests/Http/Serializer/EchoController.php +++ b/tests/Http/Serializer/EchoController.php @@ -12,10 +12,11 @@ public function __invoke( #[Payload(source: PayloadSource::Get)] SampleGetInput $get, ResponseInterface $response, ): ResponseInterface { - return $response->withBody( - (new StreamFactory())->createStream( - json_encode(compact('post', 'get'), JSON_THROW_ON_ERROR), - ), - ); + $streamFactory = new StreamFactory(); + $payload = compact('post', 'get'); + $json = json_encode($payload, JSON_THROW_ON_ERROR); + $body = $streamFactory->createStream($json); + + return $response->withBody($body); } } diff --git a/tests/Http/Serializer/SampleGetInput.php b/tests/Http/Serializer/SampleGetInput.php index b66f6b6..07d72db 100644 --- a/tests/Http/Serializer/SampleGetInput.php +++ b/tests/Http/Serializer/SampleGetInput.php @@ -6,4 +6,13 @@ final class SampleGetInput { public int $page = 1; public int $perPage = 100; + /** + * @var string[] + */ + public array $lists; + /** + * @var array + */ + public array $arrays; + public BooleansInput $booleans; } diff --git a/tests/Http/Serializer/SamplePostInput.php b/tests/Http/Serializer/SamplePostInput.php index fe3879c..81a1649 100644 --- a/tests/Http/Serializer/SamplePostInput.php +++ b/tests/Http/Serializer/SamplePostInput.php @@ -8,4 +8,5 @@ final class SamplePostInput { public int $value; /** @var TagInput[] */ public array $tags; + public TagInput $tag; }