为了在实体中使用 @MaxDepth 注释,enable_max_depth
必须在序列化器上下文中显式设置该属性(例如在 @ApiPlatform 注释的配置中),因此在实体级别,因此对于每个实体
有没有办法enable_max_depth=true
为项目的所有实体定义此属性?我们可以找到一些东西api-platform.yaml
,看起来像这样:
api-platform:
serializer:
enable_max_depth: true
Run Code Online (Sandbox Code Playgroud) 有人知道如何在集合上添加额外数据吗?\n该文档详细介绍了如何在项目上添加额外数据,这转化为装饰 ItemNormalizer 服务,并且效果非常好。
\n\n但是当涉及到在实体集合上添加一些数据时,我\xe2\x80\x99m 努力寻找要装饰的规范化器。额外的数据可以是任何内容:当前登录的用户、详细的寻呼机、一些调试参数……与特定实体无关,而是与请求本身相关。
\n\n目前唯一可行的解决方案是挂钩内核事件,但这绝对不是我喜欢编写的代码:
\n\nuse ApiPlatform\\Core\\EventListener\\EventPriorities;\nuse Symfony\\Component\\EventDispatcher\\EventSubscriberInterface;\nuse Symfony\\Component\\HttpKernel\\Event\\GetResponseForControllerResultEvent;\nuse Symfony\\Component\\HttpKernel\\KernelEvents;\nuse Symfony\\Component\\Security\\Core\\Security;\nuse Symfony\\Component\\Serializer\\Normalizer\\NormalizerInterface;\n\nfinal class SerializeListener implements EventSubscriberInterface\n{\n /**\n * @var Security\n */\n private $security;\n\n /**\n * @var NormalizerInterface\n */\n private $normalizer;\n\n public function __construct(\n Security $security,\n NormalizerInterface $normalizer\n ) {\n $this->security = $security;\n $this->normalizer = $normalizer;\n }\n\n public function addCurrentUser(GetResponseForControllerResultEvent $event)\n {\n $request = $event->getRequest();\n if ($request->attributes->has(\'_api_respond\')) {\n $serialized = $event->getControllerResult();\n $data = json_decode($serialized, true);\n $data[\'hydra:user\'] = $this->normalizer->normalize(\n $this->security->getUser(),\n $request->attributes->get(\'_format\'),\n $request->attributes->get(\'_api_normalization_context\')\n );\n $event->setControllerResult(json_encode($data));\n …
Run Code Online (Sandbox Code Playgroud) 我试图掌握 api 过滤器的目的和用法,但我在网上找到的文档非常稀疏,包括“ https://api-platform.com/docs/core/filters ”。
据我了解,过滤器类型允许 api 用户根据给定策略进行过滤(例如,不检索日期为空的数据),对吧?
在类级别编写过滤器注释相当于将其编写在目标类型的每个属性上,对吗?
我想了解组过滤器,但没有一个例子。我应该从类注释中理解什么* @ApiFilter(GroupFilter::class, arguments={"parameterName"="foobargroups"})
?foobargroup 未在代码库中的其他任何地方使用。不在 DummyCar.php 示例中,也不在另一类中,谷歌甚至没有找到我一个有效的示例。
我需要的是一种方法来告诉 api 仅返回实体的一部分或另一个。groupFilter 可以吗?或者只是用来处理1-N关系?
我正在尝试对对象的所有者实施访问控制。我正在使用 LexikJWTAuthenticationBundle,当我将检查限制为角色时,访问控制有效,但在检查对象属性时会引发异常。
我在 Symfony 4.3 项目上使用由 composer 安装的 API 平台。PHP 是 7.2.19。
我可以通过检查角色来成功限制对登录用户的请求,但是当添加诸如“object.owner == user”之类的内容时,它会失败并显示“hydra:description”:“无法访问私有属性 App\Entity\Vehicle::$所有者”
这是具有相关字段的实体类。
/**
* @ApiResource(
* collectionOperations={"get"={"access_control"="is_granted('ROLE_USER')"}, "post"={"access_control"="is_granted('ROLE_USER')"}},
* itemOperations={"get"={"access_control"="is_granted('ROLE_USER') and object.owner == user"}, "put"={"access_control"="is_granted('ROLE_USER') and previous_object.owner == user"}},
* normalizationContext={"groups"={"vehicle:read"}},
* denormalizationContext={"groups"={"vehicle:write"}}
* )
* @ORM\Entity(repositoryClass="App\Repository\VehicleRepository")
* @ApiFilter(SearchFilter::class, properties={"owner": "exact"})
*/
class Vehicle
{
/**
* @Assert\NotBlank()
* @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="vehicles")
* @ORM\JoinColumn(nullable=false)
* @Groups({"vehicle:read", "vehicle:write"})
*/
private $owner;
public function getOwner(): User
{
return $this->owner;
}
}
Run Code Online (Sandbox Code Playgroud)
这应该只允许拥有的用户获取或更新车辆,但它总是以“hydra:description”失败:“无法访问私有财产 App\Entity\Vehicle::$owner”。
如果我删除了“object.owner == user”注释,但保留对 ROLE_USER 的检查,则允许该操作。
我对 API Platform 和 Vich Uploader 的 PUT 请求感到困惑,POST 工作得很好。
这是我的 MediaObject 实体的标头:
/**
* @ORM\Entity
* @ApiResource(
* iri="http://schema.org/MediaObject",
* normalizationContext={
* "groups"={"media_object_read"}
* },
* collectionOperations={
* "post"={
* "controller"=CreateMediaObjectAction::class,
* "deserialize"=false,
* "security"="is_granted('ROLE_USER')",
* "validation_groups"={"Default", "media_object_create"},
* "openapi_context"={
* "requestBody"={
* "content"={
* "multipart/form-data"={
* "schema"={
* "type"="object",
* "properties"={
* "file"={
* "type"="string",
* "format"="binary"
* }
* }
* }
* }
* }
* }
* }
* },
* "get",
* },
* …
Run Code Online (Sandbox Code Playgroud) 有没有办法直接从数据库模式创建启用 Apiplatform 的实体?
我使用 成功创建了实体php bin/console doctrine:mapping:import "App\Entity" annotation --path=src/Entity
,但现在我必须手动添加对 120 个实体中的 Apiplatform 资源的引用,例如此处。还有其他方法吗?提前致谢。
我不明白 API 平台上的错误。
\nDoctrine\\ORM\\Mapping\\ManyToOne::__construct():参数 #2 ($cascade) 必须是 ?array 类型,给定字符串,在 /Users/charleslem/symfony/API-plateform-php-8/ 中调用Api-plateform-php8-symfony5/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php 第 944 行。
\n什么说法错误讲。我没有指示。
\n我的代码:
\n第一个实体:
\n\nnamespace App\\Entity;\n\nuse ApiPlatform\\Core\\Annotation\\ApiResource;\nuse App\\Repository\\PostRepository;\nuse Doctrine\\ORM\\Mapping as ORM;\nuse Symfony\\Component\\Serializer\\Annotation\\Groups;\nuse Symfony\\Component\\Validator\\Constraints\\Length;\n\n//read:collection pour lire une collection d'article\n//read:item correspond \xc3\xa0 la lecture d'un seul item\n/*ici je souhaite afficher les attributs title et slug quand je demande une collection d'article mais afficher \n mais afficher en plus le contennu ainsi que la date quand je fais une requete d'un seul article\n*/\n\n/**\n * @ORM\\Entity(repositoryClass=PostRepository::class)\n …
Run Code Online (Sandbox Code Playgroud) 我使用 api-platform 将 symfony 5.1 api 迁移到 symfony 6。
我的应用程序有自己的用户和密码逻辑,与普通用户数据库不同,因此我必须创建 UserRepository 和 UserProvider。
我创建了一个具有登录功能的控制器,用于检查凭据并返回令牌。
在 上symfony 5
,我实现了 AbstractGuardAuthenticator 来验证令牌并加载用户。
我symfony 6
使用实现 AbstractAuthenticator 的新系统(个人意见:不如守卫清晰)。
security:
enable_authenticator_manager: true
# [...]
providers:
# used to reload user from session & other features (e.g. switch_user)
api_user_provider:
id: App\Security\UserProvider
firewalls:
# [...]
api:
pattern: ^/api/
stateless: true
provider: api_user_provider
custom_authenticators:
- App\Security\TokenAuthenticator
Run Code Online (Sandbox Code Playgroud)
<?php
namespace App\Security;
// usings
class TokenAuthenticator extends AbstractAuthenticator
{
// [...]
public function supports(Request $request): ?bool
{
if …
Run Code Online (Sandbox Code Playgroud) 我使用没有 ORM 的 api-platform。这是我的第三个 API。另外 2 个通过 Doctrine 链接到数据库。这个用于链接另外两个,因此不需要数据库。
我无法将搜索过滤器与 GET 请求一起使用,因为出现错误:
Call to a member function getClassMetadata() on null
Run Code Online (Sandbox Code Playgroud)
(因为我没有使用 ORM 映射对象...)
所以我使用 POST 请求,给我一个 201 HTTP 返回代码。
我可以得到 200 而不是这个 201(以满足 CORS...)吗?
基于 DTO 创建了一个非常简单的资源。所有逻辑都将通过自定义提供DataProvider
,并且该项目不使用注释。
资源的配置是:
<resources xmlns="https://api-platform.com/schema/metadata">
<resource class="App\Domain\Dto\ProductUpgradePrice">
<collectionOperations>
<collectionOperation name="get"/>
</collectionOperations>
<itemOperations>
<itemOperation name="get"/>
</itemOperations>
</resource>
</resources>
Run Code Online (Sandbox Code Playgroud)
实际的DTO是:
<?php declare(strict_types=1);
namespace App\Domain\Dto;
/** @psalm-immutable */
class ProductUpgradePrice
{
public function __construct(
public string $productId,
public int $regularPrice,
public int $upgradePrice
) {}
}
Run Code Online (Sandbox Code Playgroud)
当我尝试时,GET /api/product_upgrade_prices
我得到:
没有为 App\Domain\Dto\ProductUpgradePrice 类型的资源定义标识符
这是有道理的。
文档提到使用注释,@ApiProperty
但正如我之前提到的,这个项目没有注释。(自从我发布问题以来,我提交了一个 PR 来更新文档,该问题已合并,所以希望未来的用户不会遇到同样的情况)
我尝试将其添加到资源配置中:
<property name="productId">
<attribute name="identifier">true</attribute>
</property>
Run Code Online (Sandbox Code Playgroud)
但得到了相同的结果。
在不使用注释的情况下如何配置它?