---
title: "CRUD operations — Kubernetes API for Laravel | Roundly"
description: "List, find, check existence, create, update, updateOrCreate and delete any resource — with optimistic concurrency and delete options."
url: https://roundly-consulting.com/open-source/docs/kubernetes-api-for-laravel/crud
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Kubernetes API for Laravel](https://roundly-consulting.com/open-source/docs/kubernetes-api-for-laravel.md)

# CRUD operations

Operations use Laravel’s HTTP client and return resource objects hydrated from the apiserver’s response — find() returns the resource, get() a ResourcesCollection (a Laravel Collection):

```php
use RoundlyConsulting\KubernetesApi\Facades\Kubernetes;

$cluster = Kubernetes::cluster('production');

// List — a ResourcesCollection of Deployment resources
$cluster->deployments()->setNamespace('shop')->get();

// Find a single deployment — returns a Deployment resource
$cluster->deployments()->setNamespace('shop')->withName('checkout')->find();

// Check existence — a 404 becomes false, any other error still throws
$cluster->deployments()->setNamespace('shop')->withName('checkout')->existsOnCluster();
$cluster->deployments()->setNamespace('shop')->withName('checkout')->missingOnCluster();

// Create a deployment
$template = [
    'metadata' => ['labels' => ['app' => 'checkout']],
    'spec' => ['containers' => [['name' => 'app', 'image' => 'registry.example.com/checkout:v1.4.0']]],
];

$deployment = $cluster->deployments()
    ->setNamespace('shop')
    ->setName('checkout')
    ->setLabels(['app' => 'checkout'])
    ->setReplicas(3)
    ->setPodsSelectors(['app' => 'checkout'])
    ->setSpec('template', $template)
    ->create();

$deployment->wasRecentlyCreated(); // true
$deployment->exists();             // true

// Update — read, modify, write back
$cluster->deployments()
    ->setNamespace('shop')
    ->withName('checkout')
    ->find()
    ->setReplicas(5)
    ->update();

// Update if it exists, otherwise create it — send the complete desired object
$cluster->deployments()
    ->setNamespace('shop')
    ->setName('checkout')
    ->setReplicas(2)
    ->setPodsSelectors(['app' => 'checkout'])
    ->setSpec('template', $template)
    ->updateOrCreate();

// Delete a deployment
$deleted = $cluster->deployments()->setNamespace('shop')->withName('checkout')->delete();
$deleted->exists(); // false
```

## How writes behave

- create() POSTs the object; the returned resource reports wasRecentlyCreated() and exists(). For apps/v1 workloads the apiserver requires a pod selector and a pod template whose labels match it.
- update() PUTs the whole object — read it with find() first, so the payload carries the current resourceVersion and every field you didn’t change.
- updateOrCreate() finds the resource and creates it on a 404. Otherwise it copies the server’s current resourceVersion into your object and PUTs it, so a concurrent change surfaces as a typed 409 conflict instead of being silently clobbered. The PUT replaces the object — build the complete desired state, and use patch() for partial changes.
- delete() sends DeleteOptions with Foreground propagation by default and returns a resource whose exists() is false.
- existsOnCluster() and missingOnCluster() turn a 404 into a boolean; any other error still throws.

## Query parameters and delete options

Every operation takes an optional query array — \['pretty' => 1\] by default — appended to the request, so any apiserver query parameter is one argument away. delete() also accepts a Type carrying the DeleteOptions body:

```php
use RoundlyConsulting\KubernetesApi\Resources\Types\Type;

// Background cascading instead of the default Foreground
$cluster->deployments()->setNamespace('shop')->withName('checkout')
    ->delete(options: Type::make()->setPropagationPolicy('Background'));

// Any apiserver query parameter — here gracePeriodSeconds
$cluster->pods()->setNamespace('shop')->withName('checkout-5f7c9d8b6-x2kqj')
    ->delete(['gracePeriodSeconds' => 0]);
```

withName() is an alias of setName(): any with…() call is forwarded to the matching set…() method, so both read naturally in a chain.

## Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

[More ways to support, including crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/kubernetes-api-for-laravel.md)
