Which media types carry YANG data in RESTCONF, and how do the Accept and Content-Type headers decide the encoding?
answer
- two registered yang-data types
- the +json body follows RFC 7951
- one header per direction
- different status codes for input and output
basics
~20 sRESTCONF carries YANG data as application/yang-data+json (RFC 7951 rules) or application/yang-data+xml. Content-Type names the encoding of the body sent, Accept the encoding wanted back; an unsupported input format earns 415, an unacceptable output format 406.
solid answer
~50 sRFC 8040 registers two media types: `application/yang-data+xml`, encoded by YANG's XML rules, and `application/yang-data+json`, encoded by RFC 7951. A server must implement at least one and may implement both, so a client that wants to work with every server needs both. `Content-Type` must be present whenever the client sends a body and names that body's encoding; `Accept` names what the client will take back. Without `Accept`, the server should answer in the request's encoding or may pick any format it supports; with no body at all, it answers in its own preference. If the server cannot read the body's format it returns `415 Unsupported Media Type`; if it can produce none of the formats in `Accept`, `406 Not Acceptable`. Plain `application/json` is not a RESTCONF media type, and a file extension in the URI never selects a format.
go deeper
Recall the two media types, application/yang-data+json and application/yang-data+xml, and which header describes the body you send versus the reply you want.
Explain the fallbacks: no Accept means the request's encoding should be reused, no body means server preference, and 415 versus 406 separate input from output failures.
Show you have debugged it: always send Accept, read a 415's Accept header for the supported types, and never rely on a server tolerating application/json.
Weigh the cost of a server implementing only one encoding against client tooling that speaks only one, and decide what your automation standardises on.
## Two media types, one data model **RESTCONF** (RFC 8040) is an HTTP interface to data described by **YANG** modules. The data model is the same whichever way it is serialized, and RFC 8040 Section 3.2 registers exactly two serializations for it: | Media type | Encoding rules | Defined in | |---|---|---| | `application/yang-data+xml` | YANG's XML encoding (RFC 7950) | RFC 8040 §11.3.1 | | `application/yang-data+json` | the JSON encoding of YANG (RFC 7951), plus RFC 7952 for metadata | RFC 8040 §11.3.2 | The `+xml` and `+json` endings are **structured syntax name suffixes** (RFC 6838 §4.2.8): they tell a generic tool that the body parses as XML or JSON. They do not say the body is *ordinary* JSON. RFC 8040 Section 5.2 is explicit that the JSON encoding "is valid JSON, but it also has special encoding rules to identify module namespaces and provide consistent type processing of YANG data". That is why a client that builds bodies with an all-purpose JSON serializer and labels them `application/json` gets into trouble twice: the label is not one of RESTCONF's media types, and the content usually breaks RFC 7951's rules. Two further facts from Section 5.2 shape every client: - A server **MUST support one of** XML or JSON and **MAY** support both. Neither is mandatory on its own. - Consequently "a client will need to support both XML and JSON to interoperate with all RESTCONF servers". - All RESTCONF messages use the **UTF-8** character set. ## Content-Type: what the client is sending `Content-Type` describes the **request body**. RFC 8040 requires it to be present whenever the client sends a message body, so a `PUT`, `POST` or `PATCH` with a body and no `Content-Type` is already non-conforming. The server uses the header to decide which decoder applies, and the RFC says outright that file extensions in the request are not used to identify the format. ## Accept: what the client wants back `Accept` describes the **response body**. The server MUST support it, and the RFC defines the fallbacks: 1. If `Accept` is present, the server answers in one of the listed types. 2. If `Accept` is absent, the server SHOULD answer in the same encoding as the request body, or MAY choose any encoding it supports. 3. If there was no request body either (a plain `GET`), the output encoding is XML or JSON "depending on server preference". The third rule is the one that surprises people: a `GET` with no `Accept` header may come back as XML from one server and JSON from another, both correctly. Automation that parses the reply should always send `Accept`. ## The two failure codes | Situation | Status | Meaning | |---|---|---| | The server does not support the encoding named in `Content-Type` | `415 Unsupported Media Type` | it cannot read what you sent | | The server supports none of the encodings listed in `Accept` | `406 Not Acceptable` | it cannot write what you asked for | RFC 8040 cites RFC 7231 for these codes; RFC 9110 now obsoletes RFC 7231 and defines both (§15.5.7 and §15.5.16). RFC 9110 adds that a 415 response can carry an `Accept` header listing the media types that would have been accepted, which gives a client a direct hint when it guessed wrong. ```http PUT /restconf/data/example-net:ports HTTP/1.1 Host: example.com Content-Type: application/yang-data+json Accept: application/yang-data+json { "example-net:ports": { "mtu": 1500 } } ``` A server that implements only the XML encoding must refuse this request with `415`, before it ever looks at the data. ## Errors and patches follow the same rules - **Error bodies.** When a request fails with a 4xx status, the server SHOULD return an `ietf-restconf:errors` body (403 is excepted), and its `Content-Type` is `application/yang-data` with a suffix chosen by the same `Accept`-then-request logic. - **Plain patch.** A `PATCH` that merges data must carry `application/yang-data+xml` or `application/yang-data+json`. - **YANG Patch.** RFC 8072 defines separate media types, `application/yang-patch+xml` and `application/yang-patch+json`, for an ordered list of edits; the server advertises which patch formats it takes in the `Accept-Patch` header of its `OPTIONS` response. ## What this means for a client - Send `Content-Type: application/yang-data+json` (or `+xml`) on every request with a body, and build that body by RFC 7951's rules, not by a generic serializer's defaults. - Send `Accept` on every request whose reply you parse, including `GET`. - Read 415 as "wrong body format" and 406 as "wrong reply format"; they are not interchangeable, and a body that decodes but breaks a data rule normally comes back as a 400 instead. - Treat `application/json` as outside the protocol: a server that accepts it is going beyond RFC 8040, and code that relies on it breaks on the next server.
- A RESTCONF GET carries no Accept header and no body. Which encoding comes back?Whatever the server prefers. RFC 8040 Section 5.2 says that with no request input the default output encoding is XML or JSON depending on server preference, so two conforming servers can answer the same GET differently. The reply's `Content-Type` tells you which one you got; the robust fix is to send `Accept: application/yang-data+json` or `+xml` on every request whose reply you parse.
- How does a RESTCONF client find out which PATCH formats a resource accepts?It sends `OPTIONS` to the resource and reads the `Accept-Patch` header, which RFC 8040 requires the server to return. Plain patch, which merges a body into the target, uses `application/yang-data+xml` or `+json`. YANG Patch from RFC 8072, which carries an ordered list of edits including deletes, uses `application/yang-patch+xml` or `+json`.
saying these in an interview costs you the question
- RESTCONF bodies are plain application/json, so any JSON serializer works unchanged
- Every RESTCONF server must implement both the XML and the JSON encoding
- Accept describes the request body and Content-Type describes the reply
- A RESTCONF server returns 406 when it cannot parse the request body's format
- Appending .json to the RESTCONF URI selects the JSON encoding