Content Negotiation

The API system has built-in content negotiation capabilities.

API システムには、コンテンツ ネゴシエーション機能が組み込まれています。

By default, only the JSON-LD and JSON formats are enabled. However API Platform supports many more formats and can be extended.

デフォルトでは、JSON-LD および JSON 形式のみが有効になっています。ただし、API プラットフォームはさらに多くの形式をサポートしており、拡張することができます。

The framework natively supports JSON-LD (and Hydra), GraphQL, JSON:API, HAL, YAML, CSV, HTML (API docs), raw JSON and raw XML. Using the raw JSON or raw XML formats is discouraged, prefer using JSON-LD instead, which provides more feature and is as easy to use.

このフレームワークは、JSON-LD (および Hydra)、GraphQL、JSON:API、HAL、YAML、CSV、HTML (API ドキュメント)、未加工の JSON、および未加工の XML をネイティブにサポートしています。未加工の JSON または未加工の XML 形式の使用はお勧めできません。 -LD の代わりに、より多くの機能を提供し、使いやすいです。

API Platform also supports JSON Merge Patch (RFC 7396) the JSON:API PATCH formats, as well as Problem Details (RFC 7807), Hydra and JSON:API error formats.

API プラットフォームは、JSON Merge Patch (RFC 7396)、JSON:API PATCH 形式、問題の詳細 (RFC 7807)、Hydra および JSON:API エラー形式もサポートしています。

Formats screencast
Watch the Formats screencast

フォーマットのスクリーンキャストを見る

API Platform will automatically detect the best resolving format depending on:

API プラットフォームは、以下に応じて最適な解決形式を自動的に検出します。

  • enabled formats (see below)
    有効なフォーマット (下記参照)
  • the requested format, specified in either the Accept HTTP header or as an extension appended to the URL
    Accept HTTP ヘッダーまたは URL に追加された拡張子として指定された、要求された形式

Available formats are:

利用可能な形式は次のとおりです。

Format Format name MIME types Backward Compatibility guaranteed
JSON-LD jsonld application/ld+json yes
GraphQL n/a n/a yes
JSON:API jsonapi application/vnd.api+json yes
HAL jsonhal application/hal+json yes
YAML yaml application/x-yaml no
CSV csv text/csv no
HTML (API docs) html text/html no
XML xml application/xml, text/xml no
JSON json application/json no

If the client's requested format is not specified, the response format will be the first format defined in the formats configuration key (see below). If the request format is not supported, an Unsupported Media Type error will be returned.

クライアントの要求された形式が指定されていない場合、応答形式は形式構成キーで定義された最初の形式になります (以下を参照)。要求形式がサポートされていない場合、Unsupported Media Type エラーが返されます。

Examples showcasing how to use the different mechanisms are available in the API Platform test suite.

さまざまなメカニズムの使用方法を示す例は、API プラットフォーム テスト スイートで利用できます。

Configuring Formats Globally

The first required step is to configure allowed formats. The following configuration will enable the support of XML (built-in) and of a custom format called myformat and having application/vnd.myformat as MIME type.

最初に必要な手順は、許可された形式を構成することです。次の構成は、XML (組み込み) と、myformat と呼ばれるカスタム形式のサポートを有効にし、MIME タイプとして application/vnd.myformat を持ちます。

# api/config/packages/api_platform.yaml
api_platform:
    formats:
        jsonld:   ['application/ld+json']
        jsonhal:  ['application/hal+json']
        jsonapi:  ['application/vnd.api+json']
        json:     ['application/json']
        xml:      ['application/xml', 'text/xml']
        yaml:     ['application/x-yaml']
        csv:      ['text/csv']
        html:     ['text/html']
        myformat: ['application/vnd.myformat']

To enable GraphQL support, read the dedicated chapter.

GraphQL サポートを有効にするには、専用の章をお読みください。

Because the Symfony Serializer component is able to serialize objects in XML, sending an Accept HTTP header with the text/xml string as value is enough to retrieve XML documents from our API. However API Platform knows nothing about the myformat format. We need to register an encoder and optionally a normalizer for this format.

Symfony Serializer コンポーネントは XML でオブジェクトをシリアライズできるため、値として text/xml 文字列を含む Accept HTTP ヘッダーを送信するだけで、API から XML ドキュメントを取得できます。ただし、API プラットフォームは myformat 形式について何も知りません。この形式のエンコーダーとオプションでノーマライザーを登録する必要があります。

Configuring PATCH Formats

By default, API Platform supports JSON Merge Patch and JSON:API PATCH formats. Support for the JSON:API PATCH format is automatically enabled if JSON:API support is enabled. JSON Merge Patch support must be enabled explicitly:

デフォルトでは、API プラットフォームは JSON Merge Patch および JSON:API PATCH 形式をサポートしています。JSON:API サポートが有効になっている場合、JSON:API PATCH 形式のサポートは自動的に有効になります。JSON Merge Patch サポートは明示的に有効にする必要があります。

# api/config/packages/api_platform.yaml
api_platform:
    patch_formats:
        json:     ['application/merge-patch+json']
        jsonapi:  ['application/vnd.api+json']

When support for at least one PATCH format is enabled, an Accept-Patch HTTP header containing the list of supported patch formats is automatically added to all HTTP responses for items.

少なくとも 1 つの PATCH 形式のサポートが有効になっている場合、サポートされているパッチ形式のリストを含む Accept-Patch HTTP ヘッダーが、アイテムのすべての HTTP 応答に自動的に追加されます。

Configuring Error Formats

API Platform will try to send to the client the error format matching with the format request with the Accept HTTP headers (or the URL extension). For instance, if a client request a JSON-LD representation of a resource, and an error occurs, then API Platform will serialize this error using the Hydra format (Hydra is a vocabulary for JSON-LD containing a standard representation of API errors).

API プラットフォームは、Accept HTTP ヘッダー (または URL 拡張子) を持つフォーマット リクエストに一致するエラー フォーマットをクライアントに送信しようとします。たとえば、クライアントがリソースの JSON-LD 表現を要求し、エラーが発生した場合、API プラットフォームは Hydra 形式を使用してこのエラーをシリアル化します (Hydra は、API エラーの標準表現を含む JSON-LD の語彙です)。

Available formats can also be configured:

利用可能なフォーマットも構成できます。

# api/config/packages/api_platform.yaml
api_platform:
    error_formats:
        jsonproblem:                   ['application/problem+json']
        jsonld:                        ['application/ld+json']      # Hydra error formats
        jsonapi:                       ['application/vnd.api+json']

Configuring Formats For a Specific Resource or Operation

Support for specific formats can also be configured at resource and operation level using the inputFormats and outputFormats attributes. inputFormats controls the formats accepted in request bodies while outputFormats controls formats available for responses.

特定のフォーマットのサポートは、inputFormats 属性と outputFormats 属性を使用してリソースおよび操作レベルで構成することもできます。inputFormats はリクエスト本文で受け入れられるフォーマットを制御し、outputFormats は応答に使用できるフォーマットを制御します。

The format attribute can be used as a shortcut, it sets both the inputFormats and outputFormats in one time.

format 属性はショートカットとして使用でき、inputFormats と outputFormats の両方を一度に設定します。

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

use ApiPlatform\Metadata\ApiResource;

#[ApiResource(formats: ['xml', 'jsonld', 'csv' => ['text/csv']])]
class Book
{
    // ...
}

In the example above, xml or jsonld will be allowed and there is no need to specify the MIME types as they are already defined in the configuration. Additionally the csv format is added with the MIME type text/csv.

上記の例では、xml または jsonld が許可され、構成で既に定義されているため、MIME タイプを指定する必要はありません。さらに、MIME タイプ text/csv で csv 形式が追加されます。

It is also important to notice that the usage of this attribute will override the formats defined in the configuration, therefore this configuration might disable the json or the html on this resource for example.

この属性を使用すると、構成で定義された形式がオーバーライドされることに注意することも重要です。したがって、この構成は、たとえば、このリソースの json または html を無効にする可能性があります。

You can specify different accepted formats at operation level too, it's especially convenient for to configure formats available for the PATCH method:

操作レベルでもさまざまな受け入れられる形式を指定できます。これは、PATCH メソッドで使用できる形式を構成する場合に特に便利です。

[codeSelector]

[コードセレクター]

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

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

#[ApiResource(formats: ['jsonld', 'csv' => ['text/csv']], operations: [
    new Patch(inputFormats: ['json' => ['application/merge-patch+json']]),
    new GetCollection(),
    new Post(),
])]
class Book
{
    // ...
}
resources:
    App\Entity\Book:
        formats:
           0: 'jsonld' # format already defined in the config
           csv: 'text/csv'
        operations:
            ApiPlatform\Metadata\Get:
                formats:
                    json: ['application/merge-patch+json'] # works also with "application/merge-patch+json"
<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\Greeting">
        <formats>
            <format>jsonld</format> <!-- format already defined in the config -->
            <format name="csv">text/csv</format>
        </formats>

        <operations>
            <operation class="ApiPlatform\Metadata\Get">
                <inputFormats>
                    <format name="json">application/merge-patch+json</format>
                </inputFormats>
            </operation>
        </operations>
    </resource>
</resources>

[/codeSelector]

[/コードセレクター]

Supporting Custom Formats

The API Platform content negotiation system is extendable. You can add support for formats not available by default by creating custom normalizer and encoders. Refer to the Symfony documentation to learn how to create and register such classes.

API プラットフォームのコンテンツ ネゴシエーション システムは拡張可能です。カスタム ノーマライザーとエンコーダーを作成することで、デフォルトでは利用できない形式のサポートを追加できます。そのようなクラスを作成して登録する方法については、Symfony のドキュメントを参照してください。

Then, register the new format in the configuration:

次に、構成に新しい形式を登録します。

# api/config/packages/api_platform.yaml
api_platform:
    formats:
        # ...
        myformat: ['application/vnd.myformat']

API Platform will automatically call the serializer with your defined format name as format parameter during the deserialization process (myformat in the example). It will then return the result to the client with the requested MIME type using its built-in responder. For non-standard formats, a vendor, vanity or unregistered MIME type should be used.

API プラットフォームは、デシリアライズ プロセス中に、定義されたフォーマット名を使用してシリアライザーを自動的に呼び出します (例では myformat)。次に、組み込みのレスポンダーを使用して、要求された MIME タイプで結果をクライアントに返します。標準形式、ベンダー、バニティ、または未登録の MIME タイプを使用する必要があります。

Reusing the API Platform Infrastructure

Using composition is the recommended way to implement a custom normalizer. You can use the following template to start your own implementation of CustomItemNormalizer:

カスタム ノーマライザーを実装するには、コンポジションを使用することをお勧めします。次のテンプレートを使用して、CustomItemNormalizer の独自の実装を開始できます。

# api/config/services.yaml
services:
    'App\Serializer\CustomItemNormalizer':
        arguments: [ '@api_platform.serializer.normalizer.item' ]
        # Uncomment if you don't use the autoconfigure feature
        #tags: [ 'serializer.normalizer' ]

    # ...
<?php
// api/src/Serializer/CustomItemNormalizer.php
namespace App\Serializer;

use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;

final class CustomItemNormalizer implements NormalizerInterface, DenormalizerInterface
{
    private $normalizer;

    public function __construct(NormalizerInterface $normalizer)
    {
        if (!$normalizer instanceof DenormalizerInterface) {
            throw new \InvalidArgumentException('The normalizer must implement the DenormalizerInterface');
        }

        $this->normalizer = $normalizer;
    }

    public function denormalize($data, $class, $format = null, array $context = [])
    {
        return $this->normalizer->denormalize($data, $class, $format, $context);
    }

    public function supportsDenormalization($data, $type, $format = null)
    {
        return $this->normalizer->supportsDenormalization($data, $type, $format);
    }

    public function normalize($object, $format = null, array $context = [])
    {
        return $this->normalizer->normalize($object, $format, $context);
    }

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

For example if you want to make the csv format work for even complex entities with a lot of hierarchy, you have to flatten or remove overly complex relations:

たとえば、多くの階層を持つ複雑なエンティティに対しても csv 形式を機能させたい場合は、過度に複雑な関係を平坦化または削除する必要があります。

<?php
// api/src/Serializer/CustomItemNormalizer.php
namespace App\Serializer;

use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;

class CustomItemNormalizer implements NormalizerInterface, DenormalizerInterface
{
    // ...

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

        if ('csv' !== $format || !is_array($result)) {
            return $result;
        }

        foreach ($result as $key => $value) {
            if (is_array($value) && array_keys(array_keys($value)) === array_keys($value)) {
                unset($result[$key]);
            }
        }

        return $result;
    }

    // ...
}

Contributing Support for New Formats

Adding support for standard formats upstream is welcome! We'll be glad to merge new encoders and normalizers in API Platform.

アップストリームに標準形式のサポートを追加することは大歓迎です!API プラットフォームで新しいエンコーダーとノーマライザーをマージできることをうれしく思います。