# Response

> The server sends exactly one response, whose payload is one JSON object with the members version, the string 2.3.0, and capabilities, the object the Capabilities layer defines, with no tag and no length, and the response finish follows it.

Canonical: https://protocol.diverge.network/2.3.0/endpoints/info/response/
Specification revision: 2.3.0

The server sends exactly one response on the scope. The response
finish follows the response, and no frame follows the finish.

```text
[info JSON …]
```

```json
{"version":"2.3.0","capabilities":{"images_store":true,"images_registries":["docker.io"],"volumes_persistent":{"mount":true,"fuse_serve":true,"mount_many":true,"fuse_serve_many":false,"mount_and_fuse_serve":false},"volumes_ephemeral":{"mount":true,"fuse_serve":true,"mount_many":true,"fuse_serve_many":true,"mount_and_fuse_serve":true},"volumes_read_only":{"mount":true,"fuse_serve":true,"mount_many":true,"fuse_serve_many":true,"mount_and_fuse_serve":true}}}
```

- **The payload.** The payload of the response is one JSON object,
  read as [Notation](/2.3.0/endpoints/#notation) provides, running to the
  end of the frame. No tag precedes it and no length prefixes it.
  The object has exactly two members, `version` and `capabilities`,
  and the server sends no other member.
- **`version`.** A string: the revision of this specification, of
  the form `MAJOR.MINOR.PATCH`. A server that implements this
  revision sends exactly the string `2.3.0`. It sends no other
  string, and it does not send the empty string. A server that
  implements another revision sends that revision's string, as that
  revision defines it.
- **`capabilities`.** An object: the capabilities the server holds
  out, in the form the [Capabilities](/2.3.0/capabilities/) layer defines,
  member by member, with the meaning that layer gives each member and
  each member's absence. The object is the same in every `info`
  response the server sends.
- **The sequence.** Exactly one response precedes the response
  finish, and nothing follows the finish. A response finish that no
  response precedes states that the request was not served, as
  [Endpoints](/2.3.0/endpoints/) provides.
- **Malformed.** A payload that is not valid UTF-8, a payload that is
  not exactly one JSON object, an object with no `version` member, a
  `version` member that is not a string, and a `capabilities` member
  that is not an object are malformed. An object with no
  `capabilities` member is read as a server that holds out no
  capability.

The response is defined by
`diverge-sdk-rs/src/provider/endpoints/info/server/response/frame.rs`:

```rust
//! What a server's response frame carries for an info request.

use serde::{Deserialize, Serialize};

use super::Capabilities;
use crate::wire::decode::Decode;
use crate::wire::encode::{Encode, Writer};

/// What the provider says it is: the revision of this specification
/// it implements, and the capabilities it holds out.
///
/// One of these on channel `0`, then the scope finishes. The payload
/// is this struct as JSON — no tag, because there is nothing to
/// discriminate; it runs to the end, so it needs no length either.
///
/// ```json
/// {"version":"2.3.0","capabilities":{"images_store":true,
/// "images_registries":["docker.io"],"volumes_persistent":{"mount":true,
/// "fuse_serve":true,"mount_many":true,"fuse_serve_many":false,
/// "mount_and_fuse_serve":false}}}
/// ```
///
/// # The version is fixed, and the specification defines it
///
/// The revision of the specification the provider implements, which
/// is this crate's version: `MAJOR.MINOR.PATCH`, the string every
/// page of the specification prints as its revision. The handler
/// sends the crate's own, read from the manifest at compile time.
/// Nothing else is a conforming answer — not a build hash, not a
/// name, and not the empty string. A caller reads it as the first
/// fact it needs before composing anything else: which specification
/// the far end speaks.
///
/// # The capabilities are the provider's, and it states them
///
/// What of the specification this provider does — see
/// [`Capabilities`] for each, and the variant of each endpoint's
/// response that a request past them is answered with. A caller
/// reads them as the second fact: which requests to compose at all.
///
/// # There is no failure
///
/// As with [`capacity`](crate::provider::endpoints::capacity), and no
/// other response in this specification. Every other scope can come
/// back with the provider saying it could not — an image it cannot
/// supply, a container that would not start — because every other
/// scope asks it to DO something.
///
/// This asks it to say what it is, which it always knows. A provider
/// that could not answer this could not have received the question.
///
/// Which is also why there is nothing to tag. A tag tells two things
/// apart, and there are not two things.
///
/// # A newer provider is read, not refused
///
/// A member this version does not know is ignored, here and in
/// [`Capabilities`]: a provider that states a capability a caller
/// does not know is a provider the caller can still use for
/// everything it does know, and a caller that refused the answer
/// could use it for nothing.
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[derive(schemars::JsonSchema)]
pub struct Frame {
    /// The revision: `MAJOR.MINOR.PATCH`.
    pub version: String,
    /// What the provider does. Absent, nothing: a provider that holds
    /// out no capability is one that serves only what every provider
    /// serves.
    #[serde(default)]
    pub capabilities: Capabilities,
}

/// The struct as JSON, and nothing in front of it.
impl Encode for Frame {
    /// The ordinary JSON failure.
    type Error = serde_json::Error;

    fn encode(&self, out: &mut Writer<'_>) -> Result<(), Self::Error> {
        serde_json::to_writer(out, self)
    }
}

impl Decode<'_> for Frame {
    /// One way to fail: bytes that are not this struct's JSON. What
    /// the version says is the caller's to judge against the revision
    /// it expects.
    type Error = serde_json::Error;

    fn decode(bytes: &[u8]) -> Result<Self, Self::Error> {
        serde_json::from_slice(bytes)
    }
}
```

The capabilities are defined on the [Capabilities](/2.3.0/capabilities/)
page, which includes their files.
