首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >API-Platform:多个主键,带有高调获取错误

API-Platform:多个主键,带有高调获取错误
EN

Stack Overflow用户
提问于 2020-03-01 13:02:13
回答 1查看 1.7K关注 0票数 1

关于GitHub的这个问题

我试图在没有自定义控制器的情况下为具有多主键的实体添加第二个字段,并得到错误.

现在一步一步地:

DB表:

代码语言:javascript
复制
create table measure_types
(
    id                varchar(10)  not null,
    language_iso_code varchar(2)   not null,
    label             varchar(255) null,
    created_at        datetime     not null,
    updated_at        datetime     null,
    constraint measure_types_id_language_iso_code_uindex
        unique (id, language_iso_code),
    constraint measure_types_languages_iso_code_fk
        foreign key (language_iso_code) references languages (iso_code)
);

alter table measure_types
    add primary key (id, language_iso_code);

src/Entity.php

代码语言:javascript
复制
namespace Api\Entity;

use DateTime;
use DateTimeInterface;
use Doctrine\ORM\Mapping as ORM;
use Exception;

/**
 * @ORM\Table(
 *     name="measure_types",
 *     indexes={
 *         @ORM\Index(name="measure_types_uindex", columns={"id", "language_iso_code"})
 *     },
 *     uniqueConstraints={
 *         @ORM\UniqueConstraint(name="measure_types_uindex", columns={"id", "language_iso_code"})
 *     }
 * )
 * @ORM\Entity(repositoryClass="Klarstein\Api\Repository\MeasureTypeRepository")
 * @ORM\HasLifecycleCallbacks
 */
class MeasureType
{
    /**
     * @ORM\Id()
     * @ORM\Column(type="string", length=10)
     */
    private string $id;

    /**
     * @ORM\Id()
     * @ORM\ManyToOne(targetEntity="Language", fetch="EAGER")
     * @ORM\JoinColumn(name="language_iso_code", referencedColumnName="iso_code")
     */
    private Language $language;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private string $label;

    /**
     * @ORM\Column(type="datetime")
     */
    private DateTimeInterface $createdAt;

    /**
     * @ORM\Column(type="datetime", nullable=true)
     */
    private ?DateTimeInterface $updatedAt;

    public function __construct()
    {
        $this->createdAt = new DateTime();
    }

    /**
     * @ORM\PreUpdate
     *
     * @throws Exception
     */
    public function onPutHandler(): void
    {
        $this->updatedAt = new DateTime();
    }

    // ... under this comment getters and setters
}

config/api/config_type.yaml.config

代码语言:javascript
复制
resources:
  Api\Entity\MeasureType:
    properties:
      id:
        identifier: true
      language:
        identifier: true
    attributes:
      pagination_items_per_page: 25
    collectionOperations:
      get:
        normalization_context:
          groups: ['v1_get_collection']
      post:
        normalization_context:
          groups: ['v1_post_collection_response']
        denormalization_context:
          groups: ['v1_post_collection_request']
    itemOperations:
      get:
        method: 'GET'
        normalization_context:
          groups: ['v1_get_item']
      put:
        normalization_context:
          groups: ['v1_put_item_response']
        denormalization_context:
          groups: ['v1_put_item_request']
      delete:
        denormalization_context:
          groups: ['v1_delete_item']

这是工作,就目前而言:

,但我想在doc中显示,我希望有2个参数作为标识符。

我在做的是:

添加:path: '/measure_types/id={id};language={language}'config/api/measure_type.yaml

代码语言:javascript
复制
resources:
  Api\Entity\MeasureType:
    properties:
      id:
        identifier: true
      language:
        identifier: true
    attributes:
      pagination_items_per_page: 25
    collectionOperations:
      get:
        normalization_context:
          groups: ['v1_get_collection']
      post:
        normalization_context:
          groups: ['v1_post_collection_response']
        denormalization_context:
          groups: ['v1_post_collection_request']
    itemOperations:
      get:
        method: 'GET'
        path: '/measure_types/id={id};language={language}'
        normalization_context:
          groups: ['v1_get_item']
      put:
        normalization_context:
          groups: ['v1_put_item_response']
        denormalization_context:
          groups: ['v1_put_item_request']
      delete:
        denormalization_context:
          groups: ['v1_delete_item']

下一步:我有SwaggerEventRequire装饰器:

src/Swagger/SwaggerEventRequireDecorator.php

代码语言:javascript
复制
namespace Api\Swagger;

use Symfony\Component\Finder\Finder;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\Component\Yaml\Yaml;

final class SwaggerEventRequireDecorator implements NormalizerInterface
{
    private const SWAGGER_DECORATIONS = __DIR__ . '/../../config/swagger/';

    private NormalizerInterface $decorated;

    public function __construct(NormalizerInterface $decorated)
    {
        $this->decorated = $decorated;
    }

    public function normalize($object, string $format = null, array $context = [])
    {
        $docs = $this->decorated->normalize($object, $format, $context);

        $customDefinition = $this->loadDefinitions();

        foreach ($customDefinition as $path => $methods) {
            foreach ($methods as $method => $parameters) {
                foreach ($parameters as $paramKey => $paramValues) {
                    if (empty($paramValues['name'])) {
                        continue;
                    }

                    if (empty($docs['paths'][$path]) || empty($docs['paths'][$path][$method])) {
                        continue;
                    }

                    // e.g. remove an existing event parameter
                    $docs['paths'][$path][$method]['parameters'] = array_values(
                        array_filter(
                            $docs['paths'][$path][$method]['parameters'],
                            function ($param) use ($paramKey) {
                                return $param['name'] !== $paramKey;
                            }
                        )
                    );

                    // e.g. add the new definition for event
                    $docs['paths'][$path][$method]['parameters'][] = $paramValues;
                }
            }
        }

        return $docs;
    }

    public function supportsNormalization($data, string $format = null)
    {
        return $this->decorated->supportsNormalization($data, $format);
    }

    private function loadDefinitions(): array
    {
        $result = [];
        $finder = new Finder();
        $finder
            ->files()
            ->in(self::SWAGGER_DECORATIONS)
            ->name('*.yaml');

        foreach ($finder as $file) {
            $yaml = Yaml::parseFile(self::SWAGGER_DECORATIONS . $file->getFilename());
            if (empty($yaml)) {
                continue;
            }
            $result = array_unique(array_merge($result, $yaml), SORT_REGULAR);
        }

        return $result;
    }
}

和装饰配置文件: config /swagger/测量_file.file

代码语言:javascript
复制
/measure_types/id={id};language={language}:
  get:
    id:
      name: 'id'
      description: 'Measure type ID'
      in: 'path'
      required: true
      type: 'string'
      example: 'ml'
    language:
      name: 'language'
      description: 'Language ISO code'
      in: 'path'
      required: true
      type: 'string'
      example: 'de'

结果,我得到了医生的工作表格,但结果是错误的:

我想在没有自定义控制器的情况下使用它,因为我有许多实体具有多个主键,并且为每个主键添加控制器将花费大量时间。

我做错了什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-03-04 14:24:08

解决了。解决方案是在github上给凯文的。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60475383

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档