Symfony 4.4 / NelmioApiDocBundle 4.0.1 注释问题

Posted

技术标签:

【中文标题】Symfony 4.4 / NelmioApiDocBundle 4.0.1 注释问题【英文标题】:Symfony 4.4 / NelmioApiDocBundle 4.0.1 Issue with Annotations 【发布时间】:2021-09-30 19:15:10 【问题描述】:

类似的问题已经出现,但 Symfony 和 NelmioApiDoc 的版本不同。而且我不确定是这种组合还是我在上面使用 FesRestBundle 的事实。

我的问题如下:运行单元测试时出现以下错误

[语义错误] 从未导入方法 App\RestController\DnsEndpointsController::getDnsEndpointsAction() 中的注释“@OpenAPI\Annotations\Tag”。您是否可能忘记为此注释添加“使用”语句?

这是我导致此错误的相关代码:

DnsEndpointsController.php:
<?php

declare(strict_types=1);

namespace App\RestController;

(...)
use FOS\RestBundle\Controller\AbstractFOSRestController;
use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\Request\ParamFetcherInterface;
use Nelmio\ApiDocBundle\Annotation\Model;
use OpenAPI\Annotations\Get;
use OpenAPI\Annotations\Items;
use OpenAPI\Annotations\JsonContent;
use OpenAPI\Annotations\Parameter;
use OpenAPI\Annotations\Response as OAResponse;
use OpenAPI\Annotations\Schema;
use OpenAPI\Annotations\Tag;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Validator\ConstraintViolationInterface;
use Symfony\Component\Validator\ConstraintViolationListInterface;
use Symfony\Component\Validator\Validation;

class DnsEndpointsController extends AbstractFOSRestController

(...)
    /**
     * The endpoint to get all DNS Endpoints listed in the database
     *
     * This call will return all DNS Endpoints that are matching the filter criteria handed in as query parameter.
     *
     * @Rest\Route("/subjects/dnsendpoints", name="rest_api_subjects_get_dns_endpoints", methods="GET")
     *
     * @Tag("Subjects - DnsEndpoints")
     *
     * @Get(
     *     route="/subjects/dnsendpoints",
     *     @OAResponse(
     *         response=200,
     *         description="Returned when successful",
     *
     *         @JsonContent(
     *             type="array",
     *             @Items(ref=@Model(type=NsdPrdplDnsEndpoint::class))
     *         )
     *     )
     * )
     *
     * @Parameter(
     *     name="page", in="query", required=false,
     *     description="number of page requested",
     *     @Schema(type="integer")
     * )
     * @Parameter(
     *     name="perPage", in="query", required=false,
     *     description="number entries per page",
     *     @Schema(type="integer")
     * )
(...)
     *
     * @param ParamFetcherInterface $paramFetcher
     *
     * @return Response
     *
     * @throws \LogicException
     */
    public function getDnsEndpointsAction(ParamFetcherInterface $paramFetcher): Response
(...)

相关配置是这样的:

config/routes/annotations.yaml:
(...)
rest-controllers:
    resource: ../../src/RestController/
    prefix: /api
    type: annotation

和:

composer.json:
(...)
    "require": 
        "php": ">=7.1.0",
        "ext-json": "*",
        "beberlei/doctrineextensions": "^1.2",
        "composer/package-versions-deprecated": "^1.11",
        "doctrine/annotations": "^1.0",
        "doctrine/doctrine-bundle": "^2.1",
        "doctrine/doctrine-migrations-bundle": "^2.2.0",
        "doctrine/orm": "^2.6",
        "friendsofsymfony/rest-bundle": "^2.8",
        "incenteev/composer-parameter-handler": "^2.1",
        "jms/serializer-bundle": "^2.4",
        "lexik/jwt-authentication-bundle": "^2.8",
        "nelmio/api-doc-bundle": "^4.0",
        "phpdocumentor/reflection-docblock": "^4.3",
        "sensio/framework-extra-bundle": "^5.5",
        "symfony/asset": "^4.4",
        "symfony/flex": "^1.9",
        "symfony/form": "^4.4",
        "symfony/mailer": "^4.4",
        "symfony/monolog-bundle": "^3.6",
        "symfony/polyfill-apcu": "^1.0",
        "symfony/property-access": "4.4.0",
        "symfony/property-info": "4.4.0",
        "symfony/security": "^4.4",
        "symfony/security-bundle": "^4.4",
        "symfony/serializer": "4.4.0",
        "symfony/swiftmailer-bundle": "^3.1",
        "symfony/templating": "4.4.0",
        "symfony/translation": "^4.4",
        "symfony/twig-bundle": "^4.4",
        "symfony/validator": "^4.4",
        "twig/extra-bundle": "^2.12|^3.0",
        "twig/twig": "^2.12|^3.0"
    ,
(...)

请注意我对这些注释的三个问题:

    尽管我明确声明了use OpenAPI\Annotations\Tag;,但它无法识别。此注释甚至与 Zircote 中的显式示例完全类似:Swagger-PHP v3.x。另请注意,前面的@Rest\Route 已通过并正确解析。

    无论我使用像 use OpenAPI\Annotations as OA; 和随后的 @OA\Tag 这样的缩写导入还是示例中的显式类导入对结果没有影响。

    有没有办法明确地验证注解而不是等待 phpunit 运行测试?在这个阶段,我正在等待数百分钟盯着管道进度,这更加增加了我对这个问题的挫败感。

对此有任何想法吗?我错过了什么?

【问题讨论】:

关于调试(问题3):你的IDE能识别类吗?你不能在你的本地环境中执行一个请求吗?还是只运行一小部分测试? IDE 是 PHPStorm 并且可以识别没有投诉的注释类。是的,我将范围限制为仅通过单个控制器类运行。现在这么快,谢谢。 会不会和区分大小写有关? dotjoeblog.wordpress.com/2019/07/03/… 库中的实际命名空间是 OpenApi 而不是 OpenAPI 感谢@GuilhemN,这绝对是这里的(第一个)问题 - 现在转到另一个错误,其中 Tag 注释声明了一个未知参数。但这表明我在这里提到的情况是畅通的。谢谢! 【参考方案1】:

在 Windows 上使用 PHP Storm,OpenAPIOpenApi 之间的大小写不匹配没有被注意到,而测试管道在基于 linux 的主机上运行,​​因此它产生了差异。感谢@GuilhemN 发现这一点。

【讨论】:

以上是关于Symfony 4.4 / NelmioApiDocBundle 4.0.1 注释问题的主要内容,如果未能解决你的问题,请参考以下文章

Symfony 4.4 - 自定义错误模板不起作用

Symfony 4.4 - Swift Mailer 安装失败

无效的凭据消息登录 Symfony 4.4

在 Symfony 4.4 中使用 RedisTagAwareAdapter

为啥升级到 Symfony 4.4 后我不再看到错误预览页面?

Symfony 4.4 / NelmioApiDocBundle 4.0.1 注释问题