Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Endpoints with scalar return values have invalid return types #800

Open
discordier opened this issue Apr 11, 2024 · 0 comments
Open

Endpoints with scalar return values have invalid return types #800

discordier opened this issue Apr 11, 2024 · 0 comments
Labels

Comments

@discordier
Copy link
Contributor

Jane version(s) affected: 7.6.1 (probably all)

Description

How to reproduce

consider openapi3.json with the following endpoint (irrelevant parts have been omitted):

{
  "paths": {
    "/api/create": {
      "post": {
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        }
      }
    }
  }
}

When running jane on this, the client will get generated with phpdoc like:

<?php

namespace Generated;

class Client extends \Generated\Runtime\Client\Client
{
    /**
     * @return null|\Psr\Http\Message\ResponseInterface
     */
    public function postCreate(/*...*/)
    {
        // ... deserialize code here will return something like 1.
    }
}

Note the missing int in the return types.

When now we run some tool like rector or the code style fixer on this, the return types will get propagated to native return types

<?php

namespace Generated;

class Client extends \Generated\Runtime\Client\Client
{
    public function postCreate(/*...*/): null|\Psr\Http\Message\ResponseInterface
    {
        // BUG: ... deserialize code here will return something like 1 and therefore throw an type error here.
    }
}

Possible Solution

I gave it a quick shot an implemented the following solution, I do not know however if the list of handled types is exhaustive:

--- src/Component/OpenApi3/Generator/Endpoint/GetTransformResponseBodyTrait.php	2024-04-11 18:03:41.526549347 +0200
+++ src/Component/OpenApi3/Generator/Endpoint/GetTransformResponseBodyTrait.php	2024-04-11 18:07:32.957080766 +0200
@@ -278,6 +278,7 @@
             $serializeStmt = new Expr\FuncCall(new Name('json_decode'), [
                 new Node\Arg(new Expr\Variable('body')),
             ]);
+            $returnType = $this->convertResponseType($schema);
         }
 
         $contentStatement = new Stmt\Return_($serializeStmt);
@@ -302,4 +303,30 @@
 
         return [$returnType, $throwType, $contentStatement];
     }
+
+    private function convertResponseType(Schema $schema): ?string
+    {
+        $type = $schema->getType();
+        $additionalProperties = $schema->getAdditionalProperties();
+
+        if (null === $type && null !== $schema->getEnum() && \count($schema->getEnum()) > 0) {
+            $type = 'string';
+        }
+
+        if ($additionalProperties instanceof Schema
+            && 'object' === $type
+            && 'string' === $additionalProperties->getType()) {
+            return 'string';
+        }
+
+        $convertArray = [
+            'string' => 'string',
+            'number' => 'float',
+            'boolean' => 'bool',
+            'integer' => 'int',
+            'array' => 'array',
+        ];
+
+        return $convertArray[$type] ?? null;
+    }
 }

The base code is derived from the parameter handling in the non body parameter generator:

private function convertParameterType(Schema $schema): array
{
$type = $schema->getType();
$additionalProperties = $schema->getAdditionalProperties();
if (null === $type && null !== $schema->getEnum() && \count($schema->getEnum()) > 0) {
$type = 'string';
}
if ($additionalProperties instanceof Schema
&& 'object' === $type
&& 'string' === $additionalProperties->getType()) {
return ['string'];
}
$convertArray = [
'string' => ['string'],
'number' => ['float'],
'boolean' => ['bool'],
'integer' => ['int'],
'array' => ['array'],
'file' => ['string', 'resource', '\\' . StreamInterface::class],
];
return $convertArray[$type];
}

@discordier discordier added the bug label Apr 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant