Skip to content

Document laravel provider #2031

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 4, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions laravel/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,116 @@ So, if you want to access the raw data, you have two alternatives:

For instance, go to `http://127.0.0.1:8000/api/books.jsonld` to retrieve the list of `Book` resources in JSON-LD.

> [!NOTE]
> Documentation for Eloquent "API resources" encourages using the JSON:API community format.
> While we recommend preferring JSON-LD when possible, JSON:API is also supported by API Platform,
> read the [Content Negotiation](#content-negotiation) section to learn how to enable it.

Of course, you can also use your favorite HTTP client to query the API.
We are fond of [Hoppscotch](https://hoppscotch.com), a free and open source API client with good support of API Platform.


## Using Data Transfer Objects and Hooking Custom Logic

While exposing directly the data in the database is convenient for Rapid Application Development, using different classes for the internal data and the public data is a good practice for more complex projects.

As explained in our [general design considerations](../core/design.md), API Platform allows us to use the data source of our choice using a [provider](../core/state-providers.md) and Data Transfer Objects (DTOs) are first-class citizens!

Let's create our DTO:

```php
<?php

namespace App\ApiResource;

use ApiPlatform\Metadata\Get;

#[Get(uriTemplate: '/my_custom_book/{id}')]
class Book
{
public string $id;
public string $title;
}
```

and register our new directory to API Platform:

```php
// config/api-platform.php

// ...
return [
'resources' => [
app_path('ApiResource'),
app_path('Models'),
],

// ...
];
```

Then we can create the logic to retrieve the state of our `Book` DTO:

```php
<?php

namespace App\State;

use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProviderInterface;
use App\Models\Book as BookModel;

final class BookProvider implements ProviderInterface
{
public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
{
$book = BookModel::find($uriVariables['id']);
return new Book(id: $book->id, title: $book->title);
}
}
```

Register the state provider:

```php
<?php

namespace App\Providers;

use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\ServiceProvider;

class ApiServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->singleton(BookProvider::class, function (Application $app) {
return new BookProvider();
});

$this->app->tag([BookProvider::class], ProviderInterface::class);
}
}
```

Apply the provider to your operation:

```php
<?php

namespace App\ApiResource;

use ApiPlatform\Metadata\Get;
use App\State\BookProvider;

#[Get(uriTemplate: '/my_custom_book/{id}', provider: BookProvider::class)]
class Book
{
public string $id;
public string $title;
}
```

## Content Negotiation

By default, a JSON-LD response is sent [but many other formats, including CSV and JSON:API are supported](../core/content-negotiation.md).
Expand Down