80 lines
2.7 KiB
Markdown
80 lines
2.7 KiB
Markdown
# Extensions
|
|
|
|
[Extensions](https://jsonapi.org/format/1.1/#extensions) allow your API to support additional functionality that is not part of the base specification.
|
|
|
|
## Defining Extensions
|
|
|
|
Extensions can be defined by extending the `Tobyz\JsonApiServer\Extension\Extension` class and implementing two methods: `uri` and `process`.
|
|
|
|
You must return your extension's unique URI from `uri`.
|
|
|
|
For every request that includes your extension in the media type, the `handle` method will be called. If your extension is able to handle the request, it should return a PSR-7 response. Otherwise, return null to let the normal handling of the request take place.
|
|
|
|
```php
|
|
use Tobyz\JsonApiServer\Extension\Extension;
|
|
use Psr\Http\Message\ResponseInterface;
|
|
|
|
use function Tobyz\JsonApiServer\json_api_response;
|
|
|
|
class MyExtension extends Extension
|
|
{
|
|
public function uri(): string
|
|
{
|
|
return 'https://example.org/my-extension';
|
|
}
|
|
|
|
public function handle(Context $context): ?ResponseInterface;
|
|
{
|
|
if ($context->getPath() === '/my-extension') {
|
|
return json_api_response([
|
|
'my-extension:greeting' => 'Hello world!'
|
|
]);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
```
|
|
|
|
::: warning
|
|
The current implementation of extensions has no support for augmentation of standard API responses. This API may change dramatically in the future. Please [create an issue](https://github.com/tobyzerner/json-api-server/issues/new) if you have a specific use-case you want to achieve.
|
|
:::
|
|
|
|
## Registering Extensions
|
|
|
|
Extensions can be registered on your `JsonApi` instance using the `extension` method:
|
|
|
|
```php
|
|
use Tobyz\JsonApiServer\JsonApi;
|
|
|
|
$api = new JsonApi('/api');
|
|
|
|
$api->extension(new MyExtension());
|
|
```
|
|
|
|
The `JsonApi` class will automatically perform appropriate [content negotiation](https://jsonapi.org/format/1.1/#content-negotiation-servers) and activate the specified extensions on each request.
|
|
|
|
## Atomic Operations
|
|
|
|
An implementation of the [Atomic Operations](https://jsonapi.org/ext/atomic/) extension is available at `Tobyz\JsonApi\Extension\Atomic`.
|
|
|
|
When using this extension, you are responsible for wrapping the `$api->handle` call in a transaction to ensure any database (or other) operations performed are actually atomic in nature. For example, in Laravel:
|
|
|
|
```php
|
|
use Illuminate\Support\Facades\DB;
|
|
use Tobyz\JsonApiServer\Extension\Atomic;
|
|
use Tobyz\JsonApiServer\JsonApi;
|
|
|
|
$api = new JsonApi('/api');
|
|
|
|
$api->extension(new Atomic());
|
|
|
|
/** @var Psr\Http\Message\ServerRequestInterface $request */
|
|
/** @var Psr\Http\Message\ResponseInterface $response */
|
|
try {
|
|
return DB::transaction(fn() => $api->handle($request));
|
|
} catch (Exception $e) {
|
|
$response = $api->error($e);
|
|
}
|
|
```
|