> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Contracts

> Uitleg over de rol van Contracts in Laravel, het verschil met facades, injectie via type-hints en het maken van eigen Contracts.

## Wat zijn Contracts?

De "Contracts" van Laravel zijn een set interfaces die de kernservices van het framework definiëren. Zo definieert het `Illuminate\Contracts\Queue\Queue`-contract de methoden die nodig zijn voor het queuen van jobs, en het `Illuminate\Contracts\Mail\Mailer`-contract de methoden die nodig zijn voor het versturen van e-mail.

Elk contract heeft een bijbehorende implementatie die door het framework wordt geleverd. Laravel biedt bijvoorbeeld queue-implementaties voor verschillende drivers en een mailer-implementatie op basis van [Symfony Mailer](https://symfony.com/doc/current/mailer.html).

Alle Laravel Contracts staan in een [eigen GitHub-repository](https://github.com/illuminate/contracts). Dit biedt een snelle referentie naar alle beschikbare contracts en is een op zichzelf staand pakket dat je kunt gebruiken bij het bouwen van packages die met Laravel-services samenwerken.

<Info>
  Een contract is gewoon een interface. Het werkt precies hetzelfde als een PHP-interface. Laravel levert implementaties voor deze interfaces en injecteert ze via de servicecontainer.
</Info>

## Het verschil tussen Contracts en Facades

[Facades](/nl/facades) en helperfuncties bieden een eenvoudige manier om Laravel-services te gebruiken zonder dat je contracts via type-hints uit de servicecontainer hoeft te resolven. In de meeste gevallen heeft elke facade een bijbehorend contract.

De belangrijkste verschillen tussen facades en contracts zijn:

| Aspect                          | Facade                                   | Contract                                                      |
| ------------------------------- | ---------------------------------------- | ------------------------------------------------------------- |
| Declaratie van afhankelijkheden | Niet nodig (overal aan te roepen)        | Expliciet gedeclareerd in de constructor                      |
| Testen                          | Mocken met `shouldReceive()`             | Vervangen met standaard mocklibrary's                         |
| Voornaamste gebruik             | Gemakkelijk gebruik binnen de applicatie | Package-ontwikkeling, expliciet afhankelijkhedenbeheer        |
| Leesbaarheid van code           | Slechts één importregel nodig            | Afhankelijkheden in één oogopslag zichtbaar in de constructor |

<Tip>
  Facades hoef je niet op te vragen in de constructor van een klasse, maar contracts kun je definiëren als expliciete afhankelijkheid in de constructor. Sommige ontwikkelaars geven de voorkeur aan deze expliciete definitie van afhankelijkheden en gebruiken contracts. Andere ontwikkelaars geven de voorkeur aan het gemak van facades. **Over het algemeen kunnen de meeste applicaties tijdens de ontwikkeling prima facades gebruiken.**
</Tip>

## Wanneer gebruik je Contracts?

Of je contracts of facades gebruikt, hangt af van je persoonlijke voorkeur en die van je ontwikkelteam. Zowel contracts als facades kun je gebruiken om robuuste, goed testbare Laravel-applicaties te bouwen. Contracts en facades sluiten elkaar niet uit: je kunt in delen van je applicatie facades gebruiken en in andere delen op contracts vertrouwen.

Situaties waarin contracts bijzonder nuttig zijn:

* **Wanneer je een package bouwt dat met meerdere PHP-frameworks samenwerkt** — door het `illuminate/contracts`-pakket te gebruiken om de integratie met Laravel-services te definiëren, hoef je in je `composer.json` geen concrete Laravel-implementaties te vereisen.
* **Wanneer je afhankelijkheden expliciet wilt maken** — door alleen naar de constructor te kijken zie je in één oogopslag waar de klasse van afhankelijk is.
* **Wanneer je implementaties wilt kunnen vervangen** — het wordt eenvoudig om via de servicecontainer een andere implementatie te injecteren.

## Contracts gebruiken

Hoe krijg je een implementatie van een contract? Dat is eigenlijk heel eenvoudig.

Veel soorten klassen in Laravel — controllers, event-listeners, middleware, queue-jobs, route-closures — worden via de servicecontainer geresolved. Om een implementatie van een contract te krijgen, hoef je de interface dus alleen maar als "type-hint" op te nemen in de constructor van de klasse die wordt geresolved.

```mermaid theme={null}
flowchart LR
    A["Serviceprovider<br>bind(Interface, Impl)"] --> B["Servicecontainer<br>Binding registreren"]
    C["Constructor<br>Type-hint: Interface"] --> B
    B --> D["Automatische injectie<br>Implementatie van interface resolven"]
    D --> E["Instantie van concrete klasse<br>Vrij te vervangen"]
```

Kijk bijvoorbeeld naar deze event-listener:

```php theme={null}
<?php

namespace App\Listeners;

use App\Events\OrderWasPlaced;
use App\Models\User;
use Illuminate\Contracts\Redis\Factory;

class CacheOrderInformation
{
    /**
     * Maak de event-listener aan
     */
    public function __construct(
        protected Factory $redis,
    ) {}

    /**
     * Verwerk het event
     */
    public function handle(OrderWasPlaced $event): void
    {
        // ...
    }
}
```

Wanneer de event-listener wordt geresolved, leest de servicecontainer de type-hints in de constructor van de klasse en injecteert de juiste waarden.

## Eigen Contracts maken

Door eigen contracts te maken, kun je de afhankelijkheden tussen de componenten van je applicatie duidelijk maken.

<Steps>
  <Step title="Definieer een interface">
    Maak een interface aan in de map `app/Contracts`.

    ```php theme={null}
    <?php

    namespace App\Contracts;

    interface PaymentGateway
    {
        /**
         * Reken het opgegeven bedrag af
         */
        public function charge(int $amount, string $token): bool;

        /**
         * Betaal een transactie terug
         */
        public function refund(string $transactionId): bool;
    }
    ```
  </Step>

  <Step title="Maak een implementatieklasse">
    Maak een klasse die het contract implementeert.

    ```php theme={null}
    <?php

    namespace App\Services;

    use App\Contracts\PaymentGateway;

    class StripePaymentGateway implements PaymentGateway
    {
        public function charge(int $amount, string $token): bool
        {
            // Betalingsverwerking via de Stripe API...
            return true;
        }

        public function refund(string $transactionId): bool
        {
            // Terugbetalingsverwerking via de Stripe API...
            return true;
        }
    }
    ```
  </Step>

  <Step title="Bind ze in een serviceprovider">
    Bind het contract en de implementatie in een [serviceprovider](/nl/service-providers).

    ```php theme={null}
    use App\Contracts\PaymentGateway;
    use App\Services\StripePaymentGateway;

    $this->app->singleton(PaymentGateway::class, StripePaymentGateway::class);
    ```
  </Step>

  <Step title="Ontvang de injectie via een type-hint">
    Gebruik een type-hint in de constructor van een controller of andere klasse.

    ```php theme={null}
    <?php

    namespace App\Http\Controllers;

    use App\Contracts\PaymentGateway;
    use Illuminate\Http\Request;

    class OrderController extends Controller
    {
        public function __construct(
            protected PaymentGateway $payment,
        ) {}

        public function store(Request $request)
        {
            $this->payment->charge(
                $request->amount,
                $request->payment_token
            );

            // ...
        }
    }
    ```
  </Step>
</Steps>

Dankzij dit patroon hoef je, als je de betalingsservice van `Stripe` naar een andere provider wilt overzetten, alleen de binding op één plek te wijzigen; de code van je controller blijft ongewijzigd.

## Overzicht van de belangrijkste Contracts

Een overzicht van veelgebruikte contracts en hun bijbehorende facades (selectie).

| Contract                                        | Bijbehorende facade   |
| ----------------------------------------------- | --------------------- |
| `Illuminate\Contracts\Auth\Access\Gate`         | `Gate`                |
| `Illuminate\Contracts\Auth\Factory`             | `Auth`                |
| `Illuminate\Contracts\Bus\Dispatcher`           | `Bus`                 |
| `Illuminate\Contracts\Cache\Factory`            | `Cache`               |
| `Illuminate\Contracts\Cache\Repository`         | `Cache::driver()`     |
| `Illuminate\Contracts\Config\Repository`        | `Config`              |
| `Illuminate\Contracts\Console\Kernel`           | `Artisan`             |
| `Illuminate\Contracts\Container\Container`      | `App`                 |
| `Illuminate\Contracts\Encryption\Encrypter`     | `Crypt`               |
| `Illuminate\Contracts\Events\Dispatcher`        | `Event`               |
| `Illuminate\Contracts\Filesystem\Factory`       | `Storage`             |
| `Illuminate\Contracts\Filesystem\Filesystem`    | `Storage::disk()`     |
| `Illuminate\Contracts\Hashing\Hasher`           | `Hash`                |
| `Illuminate\Contracts\Mail\Mailer`              | `Mail`                |
| `Illuminate\Contracts\Notifications\Dispatcher` | `Notification`        |
| `Illuminate\Contracts\Queue\Factory`            | `Queue`               |
| `Illuminate\Contracts\Queue\Queue`              | `Queue::connection()` |
| `Illuminate\Contracts\Queue\ShouldQueue`        | —                     |
| `Illuminate\Contracts\Redis\Factory`            | `Redis`               |
| `Illuminate\Contracts\Routing\ResponseFactory`  | `Response`            |
| `Illuminate\Contracts\Routing\UrlGenerator`     | `URL`                 |
| `Illuminate\Contracts\Session\Session`          | `Session::driver()`   |
| `Illuminate\Contracts\Translation\Translator`   | `Lang`                |
| `Illuminate\Contracts\Validation\Factory`       | `Validator`           |
| `Illuminate\Contracts\View\Factory`             | `View`                |

Een overzicht van alle contracts vind je in de [illuminate/contracts](https://github.com/illuminate/contracts)-repository.

## Volgende stappen

<Card title="Facades" icon="layer-group" href="/nl/facades">
  Bekijk hoe facades werken en hoe je ze test.
</Card>


## Related topics

- [Support Contracts (Arrayable / Jsonable / Htmlable / Responsable)](/nl/advanced/support-contracts.md)
- [Upgradegids van Laravel 12 naar 13](/nl/blog/upgrade-12-to-13.md)
- [Upgraden van Laravel 10 naar 11](/nl/blog/upgrade-10-to-11.md)
- [Een custom agent voor Boost maken](/nl/advanced/boost-custom-agent.md)
- [Een custom authenticatieguard implementeren](/nl/advanced/custom-auth-guard.md)
