簡體   English   中英

API 平台:帶有 swagger 的多個主鍵 - 出現錯誤

[英]API-Platform: Multiple primary key with swagger - getting error

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
}

配置/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平台截圖

我想在文檔中顯示,我希望有 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'

結果,我在文檔中得到了工作表,但結果錯誤:

api平台截圖

我想在沒有自定義控制器的情況下使用它,因為我有許多具有多個主鍵的實體,並且為每個實體添加控制器會花費很多時間

我做錯了什么?

解決了。 解決方案是在github 上給了 Kevin。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM