---
title: "Attributes, labels & annotations — Kubernetes API | Roundly"
description: "Dot-path attribute access, spec and status helpers, labels, annotations, magic accessors, dirty tracking and serialisation on every resource."
url: https://roundly-consulting.com/open-source/docs/kubernetes-api-for-laravel/attributes
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)

# Attributes, labels & annotations

A resource is a thin, Eloquent-style wrapper around the raw Kubernetes object. Read and write any field by dot path, and use the helpers for the common ones:

```php
$checkout = $cluster->deployments()->setNamespace('shop')->withName('checkout')->find();

// Any field, by dot path
$checkout->getAttribute('metadata.uid');
$checkout->getAttribute('spec.template.spec.containers.0.image');
$checkout->setAttribute('spec.revisionHistoryLimit', 5);

// Spec and status helpers
$checkout->getSpec('strategy.type', 'RollingUpdate');
$checkout->setSpec('paused', true);
$checkout->getStatus('observedGeneration');

// Labels and annotations
$checkout->setLabel('team', 'payments')->removeLabel('legacy');
$checkout->setAnnotation('example.com/owner', 'payments-team');
$checkout->getLabels();                        // array<string, string>
$checkout->getAnnotation('prometheus.io/scrape', 'false');

// Change tracking against what the server returned
$checkout->isDirty();                          // true
$checkout->getOriginal('spec.paused');
$checkout->discardChanges();                   // back to the loaded copy
$checkout->sync();                             // accept the current state as the original

// Serialisation
$checkout->toArray();                          // kind and apiVersion always filled in
$checkout->toJson(JSON_PRETTY_PRINT);
```

## Magic accessors

Unknown set…(), get…(), addTo…(), remove…() and getOriginal…() calls map onto a top-level attribute named after the rest of the method — only the leading verb is stripped, so getTargetPort() reads targetPort — and with…() forwards to set…(). They work on resources and on value objects such as Container:

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

$worker = Container::make()
    ->setName('worker')                        // name
    ->setImagePullPolicy('IfNotPresent')       // imagePullPolicy
    ->setCommand(['php', 'artisan', 'queue:work']);

$worker->addToArgs('--tries=3');               // appends to args
$worker->getImagePullPolicy();                 // 'IfNotPresent'
$worker->removeCommand();                      // unsets command

// withX() forwards to setX()
$cluster->deployments()->withName('checkout'); // same as ->setName('checkout')
```

Magic accessors address top-level fields only — for anything under spec use setSpec() and getSpec(), which take dot paths.

## Reference

| Method | Purpose |
| --- | --- |
| `getAttribute($path, $default) / setAttribute($path, $value)` | Read or write any field by dot path. |
| `addToAttribute($path, $value) / removeAttribute($path)` | Append to a list; unset a path. |
| `setAttributes([...]) / removeAttributes()` | Replace or clear the whole object. |
| `setName() / getName()` | metadata.name — getName() returns null for an unnamed resource, such as a pod template. |
| `setNamespace() / getNamespace()` | metadata.namespace — ignored on cluster-scoped kinds, default when unset. |
| `setLabels() · setLabel() · getLabels() · getLabel() · removeLabel()` | metadata.labels. |
| `setAnnotations() · setAnnotation() · getAnnotations() · getAnnotation() · removeAnnotation()` | metadata.annotations. |
| `setSpec() · addToSpec() · getSpec() · removeSpec()` | spec.\* by dot path, on resources with a spec. |
| `getStatus() · getStatusPhase() · statusPhaseIs()` | status.\* by dot path, on resources with a status. |
| `getKind() · getVersion() · getPluralKind()` | kind, apiVersion and the REST plural used in URLs. |
| `isDirty() · getOriginal() · discardChanges() · sync()` | Change tracking against the loaded copy. |
| `exists() · wasRecentlyCreated()` | Existence flags set by find, create and delete. |
| `toArray() · toJson() · dump() · dd()` | Serialise or inspect the payload — kind and apiVersion are filled into the output only, so serialising never makes a resource dirty. |

## Maps stay JSON objects

String-keyed maps always encode as JSON objects — metadata.labels and annotations, ConfigMap data and binaryData, Secret data and stringData, and the labels and annotations inside a pod template (spec.template) or a CronJob’s job template — even when every key is a numeric string ({"0": "a"}), which PHP would otherwise turn into a list the apiserver refuses. An empty setLabels(\[\]) or setAnnotations(\[\]), or removing the last label or annotation, sends {}.

## 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)
