<p>Im using the following code inside kubebuilder controller to read before update for k8s custom resource, im checking if the object exist if yes check if need to update, if not create it , as I need to use it in several places
I want to ask:</p>
<ul>
<li><p>if there is some helper that can help me to reduce this boilarplate
code ? something like <code>createOrUpdate</code> func</p>
</li>
<li><p>am I doing it right ?</p>
</li>
</ul>
<pre><code>if err := r.Get(ctx, client.ObjectKey{Name: sCrName, Namespace: sCrNs}, &amp;eCmp); err != nil {
    if apierrors.IsNotFound(err) {
        // If the object does not exist, create a new one
        if err := r.Create(ctx, &amp;eCmp); err != nil {
            return ctrl.Result{}, err
        }
    } else {
        // If there was an error other than 'not found', return the error
        return ctrl.Result{}, err
    }
} else {
    // If the object exists, patch it
    patch := client.MergeFrom(eCmp.DeepCopy())
    if err := r.Patch(ctx, &amp;eCmp, patch); err != nil {
        return ctrl.Result{}, err
    }
}
</code></pre>
<p><strong>if enverything is as recomended please let me know.</strong>
I need also to do the stratgic merge but the code doesnt support it</p>
<p>I found the following
<a href="https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil#CreateOrUpdate" rel="nofollow noreferrer">https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil#CreateOrUpdate</a>
but I dont want it to be related to timestamp, just <code>if something was change -&gt; update it</code> or something <code>doesnt exist -&gt; create it</code></p>
<p><strong>when trying to update the CR with the following code it doesnt works , any idea?</strong></p>
<pre><code>// If the object exists, patch it
patch := client.MergeFrom(eCmp.DeepCopy())
if err := r.Patch(ctx, &amp;eCmp, patch); err != nil {
    return ctrl.Result{}, err
}
</code></pre>

PeterSO
<p>you can use the controllerutil.CreateOrUpdate() function from the sigs.k8s.io/controller-runtime/pkg/controller/controllerutil package to reduce boilerplate code.</p>
<p>use controllerutil.CreateOrUpdate() function:</p>
<pre><code>if err := controllerutil.CreateOrUpdate(ctx, r.Client, &amp;eCmp, func() error {
    return r.Patch(ctx, &amp;eCmp, client.MergeFrom(eCmp.DeepCopy()))
}); err != nil {
    return ctrl.Result{}, err
}
</code></pre>
<p>strategic merge, you can add the strategic merge patch to the callback function to patch the object strategically</p>
<pre><code>  if err := controllerutil.CreateOrUpdate(ctx, r.Client, &amp;eCmp, func() error {
        // Create a strategic merge patch
        strategicMergePatch, err := strategicpatch.CreateTwoWayMergePatch(eCmp, &amp;newECmp, eCmp)
        if err != nil {
            return err
        }
    
        // Patch the object strategically
        return r.Patch(ctx, &amp;eCmp, client.ConstantPatch(types.StrategicMergePatchType, strategicMergePatch))
    }); err != nil {
        return ctrl.Result{}, err
    }
</code></pre>
