常见问题 (FAQ)
共享参数配置
问:我在多个端点中使用相同的值。如何避免重复描述?
答:您可以在 nelmio_api_doc 配置中配置 schemas
,然后引用它们
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
# config/nelmio_api_doc.yaml
nelmio_api_doc:
documentation:
components:
schemas:
NelmioImageList:
description: "Response for some queries"
type: object
properties:
total:
type: integer
example: 42
items:
type: array
items:
$ref: "#/components/schemas/ImageMetadata"
1 2 3 4 5 6 7 8 9
// src/App/Controller/NelmioController.php
/**
* @OA\Response(
* response=200,
* description="List of image definitions",
* @OA\JsonContent(
* ref="#/components/schemas/NelmioImageList",
* )
*/
可选路径参数
问:我有一个控制器,带有一个可选路径参数。在 swagger-ui 中,该参数是必需的 - 我可以使其成为可选参数吗?控制器可能如下所示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/**
* Get all user meta or metadata for a specific field.
*
* @Route("/{user}/meta/{metaName}",
* methods={"GET"},
* name="get_user_metadata"
* )
*
* @OA\Response(
* response=200,
* description="Json object with all user meta data or a json string with the value of the requested field"
* )
*/
public function getAction(string $user, string $metaName = null)
{
...
}
答:OpenAPI 规范不支持可选路径参数。解决此问题的方法是在控制器中定义两个单独的操作。例如
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
/**
* Get all user meta data.
*
* @Route("/{user}/meta",
* methods={"GET"},
* name="get_user_metadata"
* )
*
* @OA\Response(
* response=200,
* description="Json hashmap with all user meta data",
* @OA\JsonContent(@OA\Schema(
* type="object",
* example={"foo": "bar", "hello": "world"}
* ))
* )
*/
public function cgetAction(string $user)
{
return $this->getAction($user, null);
}
/**
* Get user meta for a specific field.
*
* @Route("/{user}/meta/{metaName}",
* methods={"GET"},
* name="get_user_metadata_single"
* )
*
* @OA\Response(
* response=200,
* description="A json string with the value of the requested field",
* @OA\JsonContent(@OA\Schema(
* type="string"
* ))
* )
*/
public function getAction(string $user, string $metaName = null)
{
...
}
第一个操作对于 Symfony 来说是多余的,但为 OpenAPI 规范添加了所有相关的文档。
资源文件未加载
问:如何修复 NelmioApiDocBundle 资源文件(css、js、图像)上的 404 或 406 HTTP 状态?
答:如果任何命令事件(通常是 post-install-cmd
或 post-update-cmd
)触发 ScriptHandler::installAssets
脚本,则资源通常由 composer 安装。如果您没有设置此脚本,您可以手动执行此命令
1
$ php bin/console assets:install --symlink
重新添加 Google 字体
问:如何更改 UI 的字体?
答:我们在 3.3 版本中移除了 google 字体,以避免因 GDPR 原因而进行外部请求。要更改字体,您可以自定义模板以添加此样式信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
{# templates/bundles/NelmioApiDocBundle/SwaggerUi/index.html.twig #}
{#
To avoid a "reached nested level" error an exclamation mark `!` has to be added
See https://symfony.com.cn/blog/new-in-symfony-3-4-improved-the-overriding-of-templates
#}
{% extends '@!NelmioApiDoc/SwaggerUi/index.html.twig' %}
{% block stylesheets %}
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700">
{{ parent() }}
<style type="text/css" rel="stylesheet">
#formats {
font-family: Open Sans,sans-serif;
}
.swagger-ui .opblock-tag,
.swagger-ui .opblock .opblock-section-header label,
.swagger-ui .opblock .opblock-section-header h4,
.swagger-ui .opblock .opblock-summary-method,
.swagger-ui .tab li,
.swagger-ui .scheme-container .schemes>label,
.swagger-ui .loading-container .loading:after,
.swagger-ui .btn,
.swagger-ui .btn.cancel,
.swagger-ui select,
.swagger-ui label,
.swagger-ui .dialog-ux .modal-ux-content h4,
.swagger-ui .dialog-ux .modal-ux-header h3,
.swagger-ui section.models h4,
.swagger-ui section.models h5,
.swagger-ui .model-title,
.swagger-ui .parameter__name,
.swagger-ui .topbar a,
.swagger-ui .topbar .download-url-wrapper .download-url-button,
.swagger-ui .info .title small pre,
.swagger-ui .scopes h2,
.swagger-ui .errors-wrapper hgroup h4 {
font-family: Open Sans,sans-serif!important;
}
</style>
{% endblock stylesheets %}
端点分组
问:区域功能不符合我的需求。那么如何在一个或多个控制器的相似端点在文档中分组到一个单独的部分?
答:使用 #[OA\Tag]
attribute。
1 2 3 4 5 6 7 8 9
/**
* Class BookmarkController
*
* @OA\Tag(name="Bookmarks")
*/
class BookmarkController extends AbstractFOSRestController implements ContextPresetInterface
{
// ...
}
禁用默认部分
问:我不想渲染“默认”部分,我该如何做?
答:在您的区域中使用 disable_default_routes
配置。
1 2 3 4
nelmio_api_doc:
areas:
default:
disable_default_routes: true
覆盖表单或纯 PHP 对象 Schema 类型
问:我想定义一个 PHP 对象或表单,其类型不是 object
,我该如何做?
答:通过使用带有 type
或 ref
的 #[OA\Schema]
属性/注解。但是请注意,type="object"
仍然会读取模型的所有属性。
1 2 3 4 5 6 7 8 9 10 11 12 13
use Nelmio\ApiDocBundle\Annotation\Model;
use OpenApi\Annotations as OA;
/**
* @OA\Schema(type="array", @OA\Items(ref=@Model(type=SomeEntity::class)))
*
* or define a `ref`:
* @OA\Schema(ref="#/components/schemas/SomeRef")
*/
class SomeCollection implements \IteratorAggregate
{
// ...
}
PropertyInfo 组件无法猜测类型
问:我有一个未被识别的属性。如何指定类型?
4.35
TypeInfo 组件 在 Symfony 7.2 中作为稳定功能引入。
答:如果您想自定义对象属性的文档,您可以使用 #[OA\Property]
属性或使用 @var
注解属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
use Nelmio\ApiDocBundle\Attribute\Model;
use OpenApi\Annotations as OA;
class User
{
/**
* @var int
* @OA\Property(description="The unique identifier of the user.")
*/
public $id;
/**
* @OA\Property(type="string", maxLength=255)
*/
public $username;
/**
* @OA\Property(ref=@Model(type=User::class))
*/
public $friend;
/**
* @OA\Property(description="This is my coworker!")
*/
public setCoworker(User $coworker) {
// ...
}
}