Operations

API Platform relies on the concept of operations. Operations can be applied to a resource exposed by the API. From an implementation point of view, an operation is a link between a resource, a route and its related controller.

API Platform は操作の概念に依存しています。 API によって公開されたリソースに操作を適用できます。実装の観点から見ると、操作はリソース、ルート、および関連するコントローラー間のリンクです。

Operations screencast
Watch the Operations screencast

オペレーションのスクリーンキャストを見る

API Platform automatically registers typical CRUD operations and describes them in the exposed documentation (Hydra and Swagger). It also creates and registers routes corresponding to these operations in the Symfony routing system (if it is available).

API プラットフォームは、一般的な CRUD 操作を自動的に登録し、公開されたドキュメント (Hydra および Swagger) でそれらを説明します。また、これらの操作に対応するルートを作成し、Symfony ルーティング システムに登録します (利用可能な場合)。

The behavior of built-in operations is briefly presented in the Getting started guide.

組み込み操作の動作は、入門ガイドで簡単に説明されています。

The list of enabled operations can be configured on a per-resource basis. Creating custom operations on specific routes is also possible.

有効な操作のリストは、リソースごとに構成できます。特定のルートでカスタム オペレーションを作成することも可能です。

There are two types of operations: collection operations and item operations.

操作には、コレクション操作とアイテム操作の 2 種類があります。

Collection operations act on a collection of resources. By default two routes are implemented: POST and GET. Item operations act on an individual resource. Three default routes are defined: GET, PUT and DELETE (PATCH is also supported when using the JSON:API format, as required by the specification).

コレクション操作は、リソースのコレクションに対して作用します。デフォルトでは、POST と GET の 2 つのルートが実装されています。アイテム操作は、個々のリソースに作用します。 GET、PUT、および DELETE の 3 つのデフォルト ルートが定義されています (仕様で要求されているように、JSON:API 形式を使用する場合は PATCH もサポートされます)。

When the ApiPlatform\Metadata\ApiResource annotation is applied to an entity class, the following built-in CRUD operations are automatically enabled:

ApiPlatform\Metadata\ApiResource アノテーションがエンティティ クラスに適用されると、次の組み込みの CRUD 操作が自動的に有効になります。

Collection operations:

コレクション操作:

Method Mandatory Description
GET yes Retrieve the (paginated) list of elements
POST no Create a new element

Item operations:

アイテム操作:

Method Mandatory Description
GET yes Retrieve an element
PUT no Replace an element
PATCH no Apply a partial modification to an element
DELETE no Delete an element

Note: the PATCH method must be enabled explicitly in the configuration, refer to the Content Negotiation section for more information.

注: PATCH メソッドは構成で明示的に有効にする必要があります。詳細については、コンテンツ ネゴシエーションのセクションを参照してください。

Note: with JSON Merge Patch, the null values will be skipped in the response.

注: JSON Merge Patch を使用すると、応答で null 値がスキップされます。

Note: Current PUT implementation behaves more or less like the PATCH method. Existing properties not included in the payload are not removed, their current values are preserved. To remove an existing property, its value must be explicitly set to null. Implementing the standard PUT behavior is on the roadmap, follow issue #4344 to track the progress.

注: 現在の PUT 実装は、多かれ少なかれ PATCH メソッドのように動作します。ペイロードに含まれていない既存のプロパティは削除されず、現在の値が保持されます。既存のプロパティを削除するには、その値を明示的に null に設定する必要があります。標準の PUT の実装問題 #4344 に従って進行状況を追跡してください。

Enabling and Disabling Operations

If no operation is specified, all default CRUD operations are automatically registered. It is also possible - and recommended for large projects - to define operations explicitly.

操作が指定されていない場合、すべての既定の CRUD 操作が自動的に登録されます。操作を明示的に定義することも可能であり、大規模なプロジェクトに推奨されます。

Keep in mind that once you explicitly set up an operation, the automatically registered CRUD will no longer be. If you declare even one operation manually, such as #[GET], you must declare the others manually as well if you need them.

操作を明示的に設定すると、自動的に登録された CRUD はなくなることに注意してください。#[GET] などの操作を 1 つでも手動で宣言する場合は、必要に応じて他の操作も手動で宣言する必要があります。

Operations can be configured using annotations, XML or YAML. In the following examples, we enable only the built-in operation for the GET method for both collection and item to create a readonly endpoint.

操作は、注釈、XML または YAML を使用して構成できます。次の例では、コレクションとアイテムの両方の GET メソッドの組み込み操作のみを有効にして、読み取り専用エンドポイントを作成します。

If the operation's name matches a supported HTTP methods (GET, POST, PUT, PATCH or DELETE), the corresponding method property will be automatically added.

操作の名前がサポートされている HTTP メソッド (GET、POST、PUT、PATCH、または DELETE) と一致する場合、対応するメソッド プロパティが自動的に追加されます。

Note: The #[GetCollection] attribute is an alias for #[Get(collection: true)]

注: #[GetCollection] 属性は #[Get(collection: true)] のエイリアスです。

[codeSelector]

[コードセレクター]

<?php
// api/src/Entity/Book.php
namespace App\Entity;

use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;

#[ApiResource(operations: [
    new Get(),
    new GetCollection()
])]
class Book
{
    // ...
}
# api/config/api_platform/resources.yaml
App\Entity\Book:
    operations:
        ApiPlatform\Metadata\GetCollection: ~ # nothing more to add if we want to keep the default controller
        ApiPlatform\Metadata\Get: ~
<?xml version="1.0" encoding="UTF-8" ?>
<!-- api/config/api_platform/resources.xml -->

<resources xmlns="https://api-platform.com/schema/metadata/resources-3.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="https://api-platform.com/schema/metadata/resources-3.0
        https://api-platform.com/schema/metadata/resources-3.0.xsd">
    <resource class="App\Entity\Book">
        <operations>
            <operation class="ApiPlatform\Metadata\Get" />
            <operation class="ApiPlatform\Metadata\GetCollection" />
        </operations>
    </resource>
</resources>

[/codeSelector]

[/コードセレクター]

The previous example can also be written with an explicit method definition:

前の例は、明示的なメソッド定義を使用して記述することもできます。

[codeSelector]

[コードセレクター]

<?php
// api/src/Entity/Book.php
namespace App\Entity;

use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;

#[ApiResource(
    operations: [
        new Get(),
        new GetCollection()
    ]
)]
class Book
{
    // ...
}
# api/config/api_platform/resources.yaml
App\Entity\Book:
    operations:
        ApiPlatform\Metadata\GetCollection:
            method: GET
        ApiPlatform\Metadata\Get:
            method: GET
<?xml version="1.0" encoding="UTF-8" ?>
<!-- api/config/api_platform/resources.xml -->

<resources xmlns="https://api-platform.com/schema/metadata/resources-3.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="https://api-platform.com/schema/metadata/resources-3.0
        https://api-platform.com/schema/metadata/resources-3.0.xsd">
    <resource class="App\Entity\Book">
        <operations>
            <operation class="ApiPlatform\Metadata\GetCollection" />
            <operation class="ApiPlatform\Metadata\Get" method="GET" />
        </operations>
    </resource>
</resources>

[/codeSelector]

[/コードセレクター]

API Platform is smart enough to automatically register the applicable Symfony route referencing a built-in CRUD action just by specifying the method name as key, or by checking the explicitly configured HTTP method.

API プラットフォームは、メソッド名をキーとして指定するか、明示的に構成された HTTP メソッドをチェックするだけで、組み込みの CRUD アクションを参照する適切な Symfony ルートを自動的に登録するほどスマートです。

If you do not want to allow access to the resource item (i.e. you don't want a GET item operation), instead of omitting it altogether, you should instead declare a GET item operation which returns HTTP 404 (Not Found), so that the resource item can still be identified by an IRI. For example:

リソース項目へのアクセスを許可したくない場合 (つまり、GET 項目操作が必要ない場合) は、それを完全に省略する代わりに、代わりに HTTP 404 (Not Found) を返す GET 項目操作を宣言する必要があります。リソース項目は IRI によって識別できます。例えば:

[codeSelector]

[コードセレクター]

<?php
// api/src/Entity/Book.php
namespace App\Entity;

use ApiPlatform\Action\NotFoundAction;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\ApiResource;

#[ApiResource(operations: [
    new Get(
        controller: NotFoundAction::class, 
        read: false, 
        output: false
    ),
    new GetCollection()
])]
class Book
{
    // ...
}
# api/config/api_platform/resources.yaml
App\Entity\Book:
    operations:
        ApiPlatform\Metadata\GetCollection: ~
        ApiPlatform\Metadata\Get:
            controller: ApiPlatform\Action\NotFoundAction
            read: false
            output: false
<?xml version="1.0" encoding="UTF-8" ?>
<!-- api/config/api_platform/resources.xml -->

<resources xmlns="https://api-platform.com/schema/metadata/resources-3.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="https://api-platform.com/schema/metadata/resources-3.0
        https://api-platform.com/schema/metadata/resources-3.0.xsd">
    <resource class="App\Entity\Book">
        <operations>
            <operation class="ApiPlatform\Metadata\GetCollection" />
            <operation class="ApiPlatform\Metadata\Get" controller="ApiPlatform\Action\NotFoundAction"
                       read="false" output="false" />
        </operations>
    </resource>
</resources>

[/codeSelector]

[/コードセレクター]

Configuring Operations

The URL, the method and the default status code (among other options) can be configured per operation.

URL、メソッド、およびデフォルトのステータス コード (他のオプションの中でも) は、操作ごとに構成できます。

In the next example, both GET and POST operations are registered with custom URLs. Those will override the URLs generated by default. In addition to that, we require the id parameter in the URL of the GET operation to be an integer, and we configure the status code generated after successful POST request to be 301:

次の例では、GET 操作と POST 操作の両方がカスタム URL に登録されています。これらは、デフォルトで生成される URL をオーバーライドします。さらに、GET 操作の URL の id パラメータを整数にする必要があり、POST リクエストが成功した後に生成されるステータス コードを 301 に設定します。

[codeSelector]

[コードセレクター]

<?php
// api/src/Entity/Book.php
namespace App\Entity;

use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\Post;

#[ApiResource(operations: [
    new Get(
        uriTemplate: '/grimoire/{id}', 
        requirements: ['id' => '\d+'], 
        defaults: ['color' => 'brown'], 
        options: ['my_option' => 'my_option_value'], 
        schemes: ['https'], 
        host: '{subdomain}.api-platform.com'
    ),
    new Post(
        uriTemplate: '/grimoire', 
        status: 301
    )
])]
class Book
{
    //...
}
# api/config/api_platform/resources.yaml
App\Entity\Book:
    operations:
        ApiPlatform\Metadata\Post:
            uriTemplate: '/grimoire'
            status: 301
        ApiPlatform\Metadata\Get:
            uriTemplate: '/grimoire/{id}'
            requirements:
                id: '\d+'
            defaults:
                color: 'brown'
            host: '{subdomain}.api-platform.com'
            schemes: ['https']
            options:
                my_option: 'my_option_value'
<?xml version="1.0" encoding="UTF-8" ?>
<!-- api/config/api_platform/resources.xml -->

<resources xmlns="https://api-platform.com/schema/metadata/resources-3.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="https://api-platform.com/schema/metadata/resources-3.0
        https://api-platform.com/schema/metadata/resources-3.0.xsd">
    <resource class="App\Entity\Book">
        <operations>
            <operation class="ApiPlatform\Metadata\Post" uriTemplate="/grimoire" status="301" />
            <operation class="ApiPlatform\Metadata\Get" uriTemplate="/grimoire/{id}" host="{subdomain}.api-platform.com">
                <requirements>
                    <requirement property="id">\d+</requirement>
                </requirements>
                <defaults>
                    <values>
                        <value name="color">brown</value>
                    </values>
                </defaults>
                <schemes>
                    <scheme>https</scheme>
                </schemes>
                <options>
                    <values>
                        <value name="color">brown</value>
                    </values>
                </options>
            </operation>
        </operations>
    </resource>
</resources>

[/codeSelector]

[/コードセレクター]

Prefixing All Routes of All Operations

Sometimes it's also useful to put a whole resource into its own "namespace" regarding the URI. Let's say you want to put everything that's related to a Book into the library so that URIs become library/book/{id}. In that case you don't need to override all the operations to set the path but configure the routePrefix attribute for the whole entity instead:

URI に関して、リソース全体を独自の「名前空間」に入れると便利な場合もあります。 URI が library/book/{id} になるように、Book に関連するすべてのものをライブラリに入れたいとします。その場合、パスを設定するためにすべての操作をオーバーライドする必要はありませんが、代わりにエンティティ全体の routePrefix 属性を構成します。

[codeSelector]

[コードセレクター]

<?php
// api/src/Entity/Book.php
namespace App\Entity;

use ApiPlatform\Metadata\ApiResource;

#[ApiResource(routePrefix: '/library')]
class Book
{
    //...
}
# api/config/api_platform/resources.yaml
App\Entity\Book:
    routePrefix: /library
<?xml version="1.0" encoding="UTF-8" ?>
<!-- api/config/api_platform/resources.xml -->

<resources xmlns="https://api-platform.com/schema/metadata/resources-3.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="https://api-platform.com/schema/metadata/resources-3.0
        https://api-platform.com/schema/metadata/resources-3.0.xsd">
    <resource class="App\Entity\Book" routePrefix="/library" />
</resources>

[/codeSelector]

[/コードセレクター]

API Platform will automatically map this post_publication operation to the route book_post_publication. Let's create a custom action and its related route using annotations:

API プラットフォームは、この post_publication オペレーションをルート book_post_publication に自動的にマッピングします。注釈を使用して、カスタム アクションとそれに関連するルートを作成しましょう。

<?php
// api/src/Controller/CreateBookPublication.php

namespace App\Controller;

use App\Entity\Book;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpKernel\Attribute\AsController;
use Symfony\Component\Routing\Annotation\Route;

#[AsController]
class CreateBookPublication extends AbstractController
{
    public function __construct(
        private BookPublishingHandler $bookPublishingHandler
    ) {}

    #[Route(
        path: '/books/{id}/publication',
        name: 'book_post_publication',
        defaults: [
            '_api_resource_class' => Book::class,
            '_api_operation_name' => '_api_/books/{id}/publication_post',
        ],
        methods: ['POST'],
    )]
    public function __invoke(Book $book): Book
    {
        $this->bookPublishingHandler->handle($book);

        return $book;
    }
}

It is mandatory to set _api_resource_class and _api_operation_namein the parameters of the route (defaults key). It allows API Platform to work with the Symfony routing system.

ルートのパラメータ(デフォルトキー)に _api_resource_class と _api_operation_name を設定することは必須です。これにより、API プラットフォームが Symfony ルーティング システムと連携できるようになります。

Alternatively, you can also use a traditional Symfony controller and YAML or XML route declarations. The following example does the exact same thing as the previous example:

または、従来の Symfony コントローラーと YAML または XML ルート宣言を使用することもできます。次の例は、前の例とまったく同じことを行います。

<?php
// api/src/Controller/BookController.php

namespace App\Controller;

use App\Entity\Book;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpKernel\Attribute\AsController;

#[AsController]
class BookController extends AbstractController
{
    public function createPublication(Book $book, BookPublishingHandler $bookPublishingHandler): Book
    {
        return $bookPublishingHandler->handle($book);
    }
}
# api/config/routes.yaml
book_post_publication:
    path: /books/{id}/publication
    methods: ['POST']
    defaults:
        _controller: App\Controller\BookController::createPublication
        _api_resource_class: App\Entity\Book
        _api_operation_name: post_publication

Defining Which Operation to Use to Generate the IRI

Using multiple operations on your resource, you may want to specify which operation to use to generate the IRI, instead of letting API Platform use the first one it finds.

リソースで複数のオペレーションを使用する場合、最初に見つかったオペレーションを API Platform に使用させるのではなく、どのオペレーションを使用して IRI を生成するかを指定したい場合があります。

Let's say you have 2 resources in relationship: Company and User, where a company has multiple users. You can declare the following routes:

会社とユーザーの 2 つのリソースの関係があるとします。会社には複数のユーザーがいます。次のルートを宣言できます。

  • /users
    /ユーザー
  • /users/{id}
    /users/{id}
  • /companies/{companyId}/users
    /companys/{companyId}/users
  • /companies/{companyId}/users/{id}
    /companys/{companyId}/users/{id}

The first routes (/users...) are only accessible by the admin, and the others by regular users. Calling /companies/{companyId}/users should return IRIs matching /companies/{companyId}/users/{id} to not expose an admin route to regular users.

最初のルート (/users...) は管理者のみがアクセスでき、他のルートは通常のユーザーがアクセスできます。 /companies/{companyId}/users を呼び出すと、/companies/{companyId}/users/{id} に一致する IRI を返して、adminroute が通常のユーザーに公開されないようにする必要があります。

To do so, use the itemUriTemplate option only available on GetCollection and Post operations:

これを行うには、GetCollection および Post 操作でのみ使用可能な itemUriTemplate オプションを使用します。

[codeSelector]

[コードセレクター]

<?php
// api/src/Entity/User.php
namespace App\Entity;

use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Post;

#[GetCollection] // auto-generated path will be /users
#[Get] // auto-generated path will be /users/{id}
#[GetCollection(uriTemplate: '/companies/{companyId}/users', itemUriTemplate: '/companies/{companyId}/users/{id}'/*, ... */)]
#[Post(uriTemplate: '/companies/{companyId}/users', itemUriTemplate: '/companies/{companyId}/users/{id}'/*, ... */)]
#[Get(uriTemplate: '/companies/{companyId}/users/{id}'/*, ... */)]
class User
{
    //...
}
# api/config/api_platform/resources.yaml
resources:
    App\Entity\User:
        - operations:
            ApiPlatform\Metadata\GetCollection: ~
            ApiPlatform\Metadata\Get: ~
        - operations:
            ApiPlatform\Metadata\GetCollection:
                uriTemplate: /companies/{companyId}/users
                itemUriTemplate: /companies/{companyId}/users/{id}
                # ...
            ApiPlatform\Metadata\Post:
                uriTemplate: /companies/{companyId}/users
                itemUriTemplate: /companies/{companyId}/users/{id}
                # ...
            ApiPlatform\Metadata\Get:
                uriTemplate: /companies/{companyId}/users/{id}
                # ...
<?xml version="1.0" encoding="UTF-8" ?>
<!-- api/config/api_platform/resources.xml -->

<resources xmlns="https://api-platform.com/schema/metadata/resources-3.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="https://api-platform.com/schema/metadata/resources-3.0
        https://api-platform.com/schema/metadata/resources-3.0.xsd">
    <resource class="App\Entity\User">
        <operations>
            <operation class="ApiPlatform\Metadata\GetCollection" />
            <operation class="ApiPlatform\Metadata\Get" />
        </operations>
    </resource>

    <resource class="App\Entity\User">
        <operations>
            <operation class="ApiPlatform\Metadata\GetCollection" uriTemplate="/companies/{companyId}/users" itemUriTemplate="/companies/{companyId}/users/{id}" />
            <operation class="ApiPlatform\Metadata\Post" uriTemplate="/companies/{companyId}/users" itemUriTemplate="/companies/{companyId}/users/{id}" />
            <operation class="ApiPlatform\Metadata\Get" uriTemplate="/companies/{companyId}/users/{id}" />
        </operations>
    </resource>
</resources>

[/codeSelector]

[/コードセレクター]

API Platform will find the operation matching this itemUriTemplate and use it to generate the IRI.

API プラットフォームは、この itemUriTemplate に一致する操作を見つけ、それを使用して IRI を生成します。

If this option is not set, the first Get operation is used to generate the IRI.

このオプションが設定されていない場合、最初の Get 操作を使用して IRI が生成されます。

Expose a Model Without Any Routes

Sometimes, you may want to expose a model, but want it to be used through subrequests only, and never through item or collection operations. Because the OpenAPI standard requires at least one route to be exposed to make your models consumable, let's see how you can manage this kind of issue.

モデルを公開したいが、それをサブリクエストのみで使用し、アイテムまたはコレクション操作では使用したくない場合があります。OpenAPI 標準では、モデルを消費可能にするために少なくとも 1 つのルートを公開する必要があるため、どのようにモデルを公開するかを見てみましょう。この種の問題を管理できます。

Let's say you have the following entities in your project:

プロジェクトに次のエンティティがあるとします。

<?php
// api/src/Entity/Place.php
namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity]
class Place
{
    #[ORM\Id, ORM\Column, ORM\GeneratedValue]
    private ?int $id = null;

    #[ORM\Column] 
    private string $name = '';

    #[ORM\Column(type: 'float')]
    private float $latitude = 0;

    #[ORM\Column(type: 'float')] 
    private float $longitude = 0;

    // ...
}
<?php
// api/src/Entity/Weather.php
namespace App\Entity;

class Weather
{
    private float $temperature;

    private float $pressure;

    // ...
}

We don't save the Weather entity in the database, since we want to return the weather in real time when it is queried. Because we want to get the weather for a known place, it is more reasonable to query it through a subresource of the Place entity, so let's do this:

データベースに Weather エンティティを保存しません。これは、クエリが実行されたときにリアルタイムで天気を返したいからです。既知の場所の天気を取得したいので、 Place エンティティなので、次のようにします。

<?php
// api/src/Entity/Place.php
namespace App\Entity;

use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\Put;
use ApiPlatform\Metadata\Delete;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Post;
use ApiPlatform\Metadata\ApiResource;
use App\Controller\GetWeather;
use Doctrine\ORM\Mapping as ORM;

#[ApiResource(
    operations: [
        new Get(),
        new Put(),
        new Delete(),
        new Get(name: 'weather', uriTemplate: '/places/{id}/weather', controller: GetWeather::class),
        new GetCollection(),
        new Post(),
    ]
)]
#[ORM\Entity]
class Place
{
    // ...

The GetWeather controller fetches the weather for the given city and returns an instance of the Weather entity. This implies that API Platform has to know about this entity, so we will need to make it an API resource too:

GetWeather コントローラーは、指定された都市の天気を取得し、Weather エンティティのインスタンスを返します。これは、API プラットフォームがこのエンティティについて知る必要があることを意味するため、API リソースも作成する必要があります。

<?php
// api/src/Entity/Weather.php
namespace App\Entity;

use ApiPlatform\Metadata\ApiResource;

#[ApiResource]
class Weather
{
    // ...

This will expose the Weather model, but also all the default CRUD routes: GET, PUT, PATCH, DELETE and POST, which is a non-sense in our context. Since we are required to expose at least one route, let's expose just one:

これにより、Weather モデルが公開されますが、すべてのデフォルトの CRUD ルート (GET、PUT、PATCH、DELETE、および POST) も公開されます。これは、このコンテキストでは無意味です。少なくとも 1 つのルートを公開する必要があるため、1 つだけ公開しましょう。 :

<?php
// api/src/Entity/Weather.php
namespace App\Entity;

use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;

#[ApiResource(operations: [
    new Get(controller: SomeRandomController::class)
])]
class Weather
{
    // ...
}

This way, we expose a route that will do… nothing. Note that the controller does not even need to exist.

このようにして、何もしないルートを公開します。コントローラーが存在する必要さえないことに注意してください。

It's almost done, we have just one final issue: our fake item operation is visible in the API docs. To remove it, we will need to decorate the Swagger documentation. Then, remove the route from the decorator:

これでほぼ完了です。最後の問題が 1 つだけあります。フェイク アイテムの操作が API ドキュメントに表示されています。これを削除するには、Swagger ドキュメントをデコレートする必要があります。次に、デコレータからルートを削除します。

<?php
// src/OpenApi/OpenApiFactory.php
namespace App\OpenApi;

use ApiPlatform\OpenApi\Factory\OpenApiFactoryInterface;
use ApiPlatform\OpenApi\OpenApi;
use ApiPlatform\OpenApi\Model;

final class OpenApiFactory implements OpenApiFactoryInterface
{
    private $decorated;

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

    public function __invoke(array $context = []): OpenApi
    {
        $openApi = $this->decorated->__invoke($context);

        $paths = $openApi->getPaths()->getPaths();

        $filteredPaths = new Model\Paths();
        foreach ($paths as $path => $pathItem) {
            // If a prefix is configured on API Platform's routes, it must appear here.
            if ($path === '/weathers/{id}') {
                continue;
            }
            $filteredPaths->addPath($path, $pathItem);
        }

        return $openApi->withPaths($filteredPaths);
    }
}

That's it: your route is gone!

それだけです:あなたのルートはなくなりました!