<p>When accessing the API server directly (i.e. not with kubectl, but with direct HTTP requests), what formats for the resource specifications does the API server support?</p>

<p>In all examples I have seen so far, the resource specifications are in JSON (for example <a href="https://github.com/kubernetes/kubernetes/issues/17404" rel="nofollow noreferrer">here</a>). But I couldn't find any general information about this.</p>

<p>Does the API server also accept resource specifications in other formats, such as YAML or protobuf?</p>

<p>Similarly, when the API server returns resources in response to a GET request, are the resources always returned in JSON or are there any other formats supported?</p>

<p><a href="https://www.oreilly.com/library/view/managing-kubernetes/9781492033905/ch04.html" rel="nofollow noreferrer">Managing Kubernetes, Chapter 4</a> (section "Alternate encodings") says that the API server supports three data formats for resource specifications:</p>

<ul>
<li>JSON</li>
<li>YAML</li>
<li>Protocol Buffers (protobuf)</li>
</ul>

<p>I tested creating resources in these formats using <code>curl</code> and it works, as shown in the following.</p>

<h3>Preparation</h3>

<p>For easily talking to the API server, start a proxy to the API server with kubectl:</p>

<pre class="lang-sh prettyprint-override"><code>kubectl proxy
</code></pre>

<p>Now the API server is accessible on <a href="http://127.0.0.1:8001" rel="nofollow noreferrer">http://127.0.0.1:8001</a>.</p>

<p>The Kubernetes API specification is accessible on <a href="http://127.0.0.1:8001/openapi/v2" rel="nofollow noreferrer">http://127.0.0.1:8001/openapi/v2</a>.</p>

<h3>Request body formats</h3>

<p>You have to specify the format of the HTTP POST request body (i.e. the resource specification) in the <code>Content-Type</code> header.</p>

<p>The following data formats are supported:</p>

<ul>
<li><code>application/json</code></li>
<li><code>application/yaml</code></li>
<li><code>application/vnd.kubernetes.protobuf</code></li>
</ul>

<p>Below are concrete examples of requests.</p>

<h3>Create a resource with JSON</h3>

<p>Define a resource specification in JSON and save it in a file.</p>

<p>For example, <code>pod.json</code>:</p>

<pre><code>{
   "apiVersion":"v1",
   "kind":"Pod",
   "metadata":{
      "name":"test-pod"
   },
   "spec":{
      "containers":[
         {
            "image":"nginx",
            "name":"nginx-container"
         }
      ]
   }
}
</code></pre>

<p>Call API server to create the resource:</p>

<pre class="lang-sh prettyprint-override"><code>curl -H "Content-Type: application/json" -d "$(cat pod.json)" -X POST http://127.0.0.1:8001/api/v1/namespaces/default/pods
</code></pre>

<h3>Create a resource with YAML</h3>

<p>Define a resource specification in YAML and save it in a file.</p>

<p>For example, <code>pod.yaml</code>:</p>

<pre><code>apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
  - image: nginx
    name: nginx-container
</code></pre>

<p>Call API server to create the resource:</p>

<pre class="lang-sh prettyprint-override"><code>curl -H "Content-Type: application/yaml" -d "$(cat pod.yaml)" -X POST http://127.0.0.1:8001/api/v1/namespaces/default/pods
</code></pre>

<h3>Create a resource with protobuf</h3>

<p>I didn't test this, because the Kubernetes protobuf wire format uses a custom wrapper around the protobuf serialisation of the resource (see <a href="https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/protobuf.md" rel="nofollow noreferrer">here</a> and <a href="https://kubernetes.io/docs/reference/using-api/api-concepts/#protobuf-encoding" rel="nofollow noreferrer">here</a>). But, in principle, it should work.</p>

<h3>Response body formats</h3>

<p>When creating a resource as shown above, the API server returns the complete specification of the same resource in the HTTP response (that is, the specification that you submitted, initialised with all the default values, a <code>status</code> field, etc.).</p>

<p>You can choose the format for this response data with the <code>Accept</code> header in the request.</p>

<p>The accepted formats for the <code>Accept</code> header are the same as for the <code>Content-Type</code> header:</p>

<ul>
<li><code>application/json</code> (default)</li>
<li><code>application/yaml</code></li>
<li><code>application/vnd.kubernetes.protobuf</code></li>
</ul>

<p>For example:</p>

<pre class="lang-sh prettyprint-override"><code>curl -H "Content-Type: application/json" -H "Accept: application/yaml" -d "$(cat pod.json)" -X POST http://127.0.0.1:8001/api/v1/namespaces/default/pods
</code></pre>

<p>All combinations of formats in the <code>Content-Type</code> and <code>Accept</code> headers are possible.</p>
