Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

Varnish invalidation on subresource

Đang mở
#8,123 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
25/100
Loại issue
Lỗi
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Đình trệ
Công nghệ
php
Lĩnh vực
api, backend

Hướng nghiên cứu

Bắt đầu bằng cách tái hiện hành vi bộ nhớ đệm của Varnish với collection /suppliers/{id}/delivery_days và một POST tới /delivery_days. Truy vết dịch vụ vô hiệu hóa bộ nhớ đệm và cấu hình route của collection được mô tả trong issue. Hoàn tất khi bộ nhớ đệm của collection tài nguyên con được vô hiệu hóa mà không làm lộ một route collection mặc định không mong muốn.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

http State

API Platform version(s) affected: 3.3.6

Description
Varnish cache is not released on a subresource.
For example purposes, I use a Supplier and a DeliveryDay entity.

Supplier:

#[ORM\Entity(repositoryClass: SupplierRepository::class)]
#[ApiResource(
    operations: [
        new Post(),
        new Get(),
        new GetCollection(),
        new Put(),
        new Delete(),
    ],
    normalizationContext: ['groups' => ['supplier:read']],
    denormalizationContext: ['groups' => ['supplier:write']],
)]
class Supplier
{

    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    #[Groups(groups: ['supplier:read'])]
    private ?int $id = null;

    #[ORM\Column(length: 128)]
    #[Groups(groups: ['supplier:read', 'supplier:write'])]
    #[Assert\NotBlank]
    #[Assert\Length(max: 128)]
    public string $name = '';

    #[ORM\OneToMany(targetEntity: DeliveryDay::class, mappedBy: 'supplier', orphanRemoval: true)]
    private Collection $deliveryDays;

    public function __construct()
    {
        $this->deliveryDays = new ArrayCollection();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    /**
     * @return Collection<int, DeliveryDay>
     */
    public function getDeliveryDays(): Collection
    {
        return $this->deliveryDays;
    }

    public function addDeliveryDay(DeliveryDay $deliveryDay): static
    {
        if (!$this->deliveryDays->contains($deliveryDay)) {
            $this->deliveryDays->add($deliveryDay);
            $deliveryDay->setSupplier($this);
        }

        return $this;
    }

    public function removeDeliveryDay(DeliveryDay $deliveryDay): static
    {
        if ($this->deliveryDays->removeElement($deliveryDay)) {
            // set the owning side to null (unless already changed)
            if ($deliveryDay->getSupplier() === $this) {
                $deliveryDay->setSupplier(null);
            }
        }

        return $this;
    }
}

DeliveryDay:

#[ORM\Entity]
#[ApiResource(
    operations: [
        new Post(),
        new Get(),
        new GetCollection(
            uriTemplate: '/suppliers/{id}/delivery_days',
            uriVariables: [
                'id' => new Link(
                    fromProperty: 'deliveryDays',
                    fromClass: Supplier::class
                ),
            ]
        ),
        new Put(),
        new Delete(),
    ],
    normalizationContext: ['groups' => ['delivery_day:read']],
    denormalizationContext: ['groups' => ['delivery_day:write']],
)]
class DeliveryDay
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    #[Groups(groups: ['delivery_day:read'])]
    private ?int $id = null;

    #[ORM\ManyToOne(inversedBy: 'deliveryDays')]
    #[ORM\JoinColumn(nullable: false)]
    #[Groups(groups: ['delivery_day:read', 'delivery_day:write'])]
    private ?Supplier $supplier = null;

    #[ORM\Column(length: 64)]
    #[Groups(groups: ['delivery_day:read', 'delivery_day:write'])]
    #[Assert\NotBlank]
    #[Assert\Length(max: 64)]
    public string $day = '';

    #[ORM\Column(length: 64)]
    #[Groups(groups: ['delivery_day:read', 'delivery_day:write'])]
    #[Assert\NotBlank]
    #[Assert\Length(max: 64)]
    public string $region = '';

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getSupplier(): ?Supplier
    {
        return $this->supplier;
    }

    public function setSupplier(?Supplier $supplier): static
    {
        $this->supplier = $supplier;

        return $this;
    }
}

How to reproduce
If you now use /suppliers/{id}/delivery_days, Varnish caches that response.
If you then make a POST request to /delivery_days, the cache from the collection route is not invalidated.

Possible Solution
If you add a default GetCollection:

new GetCollection(),
new GetCollection(
    uriTemplate: '/suppliers/{id}/delivery_days',
    uriVariables: [
        'id' => new Link(
            fromProperty: 'deliveryDays',
            fromClass: Supplier::class
        ),
    ]
),

It works, but then there is a route exposed that you don't really want.

So, I would suggest always adding a default cache tag to a collection.
In this case, that would be /delivery_days (even when the route doesn't exist)
and also add this tag to the invalidation service (even if the route doesn't exist).

end word
If I'm doing something that is not intended or missed some docs, please point me in the right direction.
I would like to help resolve this issue by contributing, but I have never done that before.
I would appreciate some help or guidance to get started.

Ngôn ngữ chính
PHP
Star
2.6k
Fork
988
Merge trung bình
1 ngày 19 giờ
Pull request đã merge (30 ngày)
105

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của api-platform/core

Tất cả issue của api-platform/core

Issue tương tự

Thêm issue về PHP

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.