API平台:多个主键,带有张大嘴-出现错误

问题描述 投票:1回答:1

This question on GitHub

我正在尝试将第二个字段添加到没有自定义控制器的参数中,以用于具有多个主键的实体并出现错误...

现在逐步:

数据库表:

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 / MeasureType.php

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 / measure_type.yaml

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']

目前正在工作:

api-platform screenshot

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

我在做什么:

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

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

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 / measure_type.yaml

/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'

结果,我在doc中得到了工作表格,但结果错误:

api-platform screenshot

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

我做错了什么?

php symfony swagger api-platform.com
1个回答
0
投票

已解决。解决方案在github上,由凯文(Kevin)提供。

© www.soinside.com 2019 - 2024. All rights reserved.