Skip to content

Provides content-negotiation using `Accept` headers for BEAR.Sunday

License

Notifications You must be signed in to change notification settings

bearsunday/BEAR.Accept

Folders and files

NameName
Last commit message
Last commit date

Latest commit

1706ecd · Jan 11, 2024

History

59 Commits
Jan 11, 2024
Jun 23, 2022
Jun 23, 2022
Jun 17, 2022
Apr 14, 2020
Aug 9, 2017
Apr 14, 2020
Jan 11, 2024
Jun 18, 2022
Jun 23, 2022
Jun 18, 2022
Aug 9, 2017
Jun 17, 2022
Jun 17, 2022
Jun 17, 2022

Repository files navigation

BEAR.Accept

Provides content-negotiation using Accept* headers for BEAR.Sunday

Composer install

$ composer require bear/accept

Module install

use Ray\Di\AbstractModule;
use Ray\Di\Scope;

class AppModule extends AbstractModule
{
    /**
     * {@inheritdoc}
     */
    protected function configure()
    {
        $available = [
            'Accept' => [
                'application/hal+json' => 'prod-hal-app',
                'application/json' => 'prod-app',
                'text/csv' => 'prod-csv-app',
                'cli' => 'prod-html-app'
            ],
            'Accept-Language' => [
                'en-US' => 'en',
                'ja-JP' => 'ja'
            ]
        ];
        // $available support 'Accept' and 'Accept-Language' key only
        $this->install(new AcceptModule($available));
    }
}

Accept specifies all of the available media in the format [$mediatype => $context]. cli is the context in case of console access. The renderer of the context of the media type matched by content negotiation is used for rendering the resource.

Accept-Language specifies all available languages in the format [$lang => $contextKey].

For example, if application/hal+json and ja-JPmatches, the $context is prod-hal-jp-app. (We set JpModule in App\Module folder and bind it for Japanese.)

Usage

Apply to the specified resource

Annotate the resource to do content negotiation with @Produces.

use use BEAR\Accept\Annotation\Produces;

/**
 * @Produces({"application/json", "text/csv"})
 */
public function onGet()

application/json and text/csv media type is available for this resource. The Vary header is added automatically.

Apply to all resources

To perform content negotiation on all resources, prepare a special bootstrap file. This is especially useful when negotiating languages.

cn.php

require dirname(__DIR__) . '/vendor/autoload.php';

$available = [
    'Accept' => [
        'text/html' => 'prod-html-app',
        'application/hal+json' => 'prod-hal-app',
        'application/json' => 'prod-app',
        'cli' => 'cli-html-app'
    ],
    'Accept-Language' => [
        'ja' => 'ja',
        'en-US' => 'us'
    ]
];
$accept = new \BEAR\Accept\Accept($available);
[$context, $vary] = $accept($_SERVER);
//

Add a vary header in Bootstrap to enable caching when using content negotiation.

+    /* @global \BEAR\Resource\Vary $vary */
+    if (isset($vary)) {
+        $page->headers['Vary'] = $vary;
+    }
     $page->transfer($app->responder, $_SERVER);

Prepare the module of the DI setting necessary for each language.

use BEAR\Sunday\Module\Constant\NamedModule;

class JaModule extends AbstractModule
{
    /**
     * {@inheritdoc}
     */
    protected function configure()
    {
        $text = ['greeting' => 'こんにちは'];
        $this->install(new NamedModule($text));
    }
}