krz/domain-dig

an ios app for DNS & SSL analysis

clone: git clone https://gitbay.org/krz/domain-dig.git

v5.0.0: LocalAPIContract.swift · raw

 1import Foundation
 2
 3/// The versioned wire contract for the Local API.
 4///
 5/// External consumers  Shortcuts, scripts, and third-party integrations  depend
 6/// on the JSON this API produces: the response envelope, the field names of every
 7/// payload, and the encoding conventions. This type is the single source of truth
 8/// for the parts that must stay stable, and `LocalAPIContractTests` pins them so
 9/// an accidental rename or shape change fails CI instead of silently breaking a
10/// consumer.
11///
12/// ## Compatibility policy
13///
14/// The `version` string reported in every envelope follows a semantic-version-style
15/// promise:
16///
17/// - **Backward-compatible** changes keep `version` at `"v1"`: adding a new
18///   endpoint, or adding a new field to a payload. Consumers must ignore unknown
19///   fields, so additions never require a bump.
20/// - **Breaking** changes require bumping `version` (and updating `Docs/local-api.md`
21///   plus the contract tests): renaming or removing a field, changing a field's
22///   type, or changing the meaning/units of an existing field.
23///
24/// See `Docs/local-api.md` for the full endpoint and schema reference.
25enum LocalAPIContract {
26    /// Wire-format version reported in every envelope's `version` field.
27    static let version = "v1"
28
29    /// The canonical encoder for every Local API response. ISO-8601 dates and
30    /// sorted keys keep the output deterministic, which is what lets the contract
31    /// tests pin the shape. Both the success and error paths route through this so
32    /// the wire format can never drift between them.
33    static func makeEncoder() -> JSONEncoder {
34        let encoder = JSONEncoder()
35        encoder.dateEncodingStrategy = .iso8601
36        encoder.outputFormatting = [.sortedKeys]
37        return encoder
38    }
39}