<p>Could anyone of you tell how to refactor the following functions, please?</p>
<p>I'd like to have one function eg. <code>getResource(name string, resourceType ????) []v1.?????</code>, but don't know what would be its return type.</p>
<pre><code>func getPods(name string) []v1.Pod {
    pods, err := clientset.CoreV1().Pods(namespace).List(context.TODO(), getListOption(name))

    if err != nil {
        panic(err.Error())
    }
    return pods.Items
}

func getServices(name string) []v1.Service {
    services, err := clientset.CoreV1().Services(namespace).List(context.TODO(), getListOption(name))

    if err != nil {
        panic(err.Error())
    }
    return services.Items
}
</code></pre>

gbajson
<p>While the invocation is nearly identical, and the content is nearly identical, they types are different.  <a href="https://pkg.go.dev/k8s.io/client-go@v0.22.3/kubernetes/typed/core/v1#PodInterface" rel="nofollow noreferrer"><code>CoreV1().Pods(namespace).List</code></a> is :</p>
<pre class="lang-golang prettyprint-override"><code>List(ctx context.Context, opts metav1.ListOptions) (*v1.PodList, error)
</code></pre>
<p>but <a href="https://pkg.go.dev/k8s.io/client-go@v0.22.3/kubernetes/typed/core/v1#ServiceInterface" rel="nofollow noreferrer"><code>CoreV1().Services(namespace).List</code></a> is</p>
<pre class="lang-golang prettyprint-override"><code>List(ctx context.Context, opts metav1.ListOptions) (*v1.ServiceList, error)
</code></pre>
<p>One returns a <code>*v1.PodList</code> and the other returns a <code>*v1.ServiceList</code>.  Both these distinct objects have <code>Items</code>, but one is a <a href="https://pkg.go.dev/k8s.io/api/core/v1#ServiceList" rel="nofollow noreferrer"><code>[]*Service</code></a> and the other is a <a href="https://pkg.go.dev/k8s.io/api/core/v1#PodList" rel="nofollow noreferrer"><code>[]*Pod</code></a>.</p>
<p>I personally would think about not wrapping either.  I would call the underlying functions instead, using the same <code>CoreV1</code> client in both cases.
I certainly wouldn't try to combine them into one function.</p>
<p>If there's something to be combined here, it's namespace and name:</p>
<pre><code>type ByName struct {
   Name string
   Namespace string
   v1 corev1.CoreV1Interface
}

func (b *ByName)Services(ctx context.Context) []v1.Service , error {
   return b.v1.Services(namespace).List(ctx,  getListOption(b.Name))
}

func (b *ByName)Pods(ctx context.Context) []v1.Pod, error {
  return b.v1.Pods(b.Namespace).List(ctx, getListOption(b.Name))
}
</code></pre>
<p>Now you don't have to pass name and namespace:</p>
<pre><code>b := &amp;ByName{
  Name: name,
  Namespace: namespace,
  v1: clientset.CoreV1(),
}

if svcs, err :=  b.Services(); err != nil {
   return nil, err
} else if pods, err := b.Pods(); err != nil {
  return nil, err
} else {
  ... continue processing
}
</code></pre>
<p>And you get the brevity you want without having to do a bunch of type checking.</p>
