使用API Platform注解的Swagger无法引用同目录JSON文件问题
问题分析与解决方案
你遇到的核心问题是Swagger/OpenAPI的$ref解析逻辑和你预期的文件系统路径不一致,API Platform生成文档时并不会直接读取实体类目录下的JSON文件,原因和解决方法如下:
1. $ref的路径规则搞反了
Swagger的$ref是基于生成的OpenAPI文档的HTTP访问路径,而不是实体类所在的服务器文件系统路径。举个例子:
- 你的实体类在
src/Entity/Entity.php,同目录的foo.json是服务器本地文件,Swagger UI根本无法通过HTTP请求到这个目录(因为src不是Web可访问目录),自然加载失败。
解决方法:把JSON放到Web可访问目录
把foo.json移动到项目的public目录下,比如public/swagger/schemas/foo.json,然后修改swagger_context的$ref为:
/** * @ApiResource( * swaggerContext={ * "responses"={ * "200"={ * "description"="Success", * "schema"={ * "$ref"="/swagger/schemas/foo.json" * } * } * } * } * ) */ class Entity { // ... }
先测试访问https://你的域名/swagger/schemas/foo.json,确保能正常返回JSON内容,然后清理缓存(php bin/console cache:clear),再刷新Swagger UI就能看到对应的schema了。
2. 本地文件引用的进阶方案(不暴露到公共目录)
如果不想把JSON文件放到公共目录,可以让API Platform在生成OpenAPI文档时直接读取本地文件并内联到文档中。你可以通过自定义Swagger文档处理器来实现:
- 创建一个自定义处理器类:
// src/Swagger/Processor/LoadLocalSchemaProcessor.php namespace App\Swagger\Processor; use ApiPlatform\Core\Swagger\Serializer\SwaggerSerializer; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; class LoadLocalSchemaProcessor implements NormalizerInterface { private $decorated; public function __construct(NormalizerInterface $decorated) { $this->decorated = $decorated; } public function normalize($object, $format = null, array $context = []) { $swagger = $this->decorated->normalize($object, $format, $context); // 读取本地foo.json并添加到components/schemas $fooSchema = json_decode(file_get_contents(__DIR__.'/../../Entity/foo.json'), true); $swagger['components']['schemas']['Foo'] = $fooSchema; return $swagger; } public function supportsNormalization($data, $format = null) { return $this->decorated->supportsNormalization($data, $format); } }
- 在
services.yaml中配置装饰器:
services: App\Swagger\Processor\LoadLocalSchemaProcessor: decorates: api_platform.swagger.normalizer.api_gateway arguments: ['@.inner']
- 修改实体类的swagger_context:
/** * @ApiResource( * swaggerContext={ * "responses"={ * "200"={ * "description"="Success", * "schema"={ * "$ref"="#/components/schemas/Foo" * } * } * } * } * ) */ class Entity { // ... }
这种方式不需要暴露JSON文件到公共网络,而是在生成文档时直接把JSON内容合并到OpenAPI的组件中,更安全。
3. 别忘了清理缓存
API Platform会缓存生成的Swagger文档,所以修改配置或文件后,一定要执行:
php bin/console cache:clear
否则你看到的可能还是旧的文档内容。
内容的提问来源于stack exchange,提问作者Assasz
相关产品推荐
相关产品推荐

