Summary
Two inconsistencies in the admin HTTP API (record handling) between the OpenAPI spec, the actual code, and DNS conventions. Surfaced while building the solutrix-api go53 integration. The OpenAPI docs have been updated to describe the current v1 behavior truthfully; this issue tracks the proper fix under a future /api/v2.
Problem
1. MX payload field names
- The MX RR handler (
zone/rtypes/mx.go) reads/writes JSON fields priority + host, and the read responses return the same. Internally/serving is already RFC-correct (dns.MX{Preference, Mx}).
- The OpenAPI spec (
MXRecordPayload, examples) instead documented preference + mx, which matches neither the code nor the read output. (RFC 1035 actually calls these preference + exchange.)
- Effect: clients following the spec get
500 "MXRecord expects field 'host'".
2. Owner-name form differs between POST and PATCH/DELETE
POST /api/zones/{zone}/records/{rrtype} takes the owner name relative in the body (www, @) and works.
PATCH/DELETE /api/zones/{zone}/records/{rrtype}/{name} pass the path {name} straight to rtype.Delete() → internal.SplitName() which requires an FQDN; a relative name fails with errors.New("invalid host format") returned as HTTP 500 (api/handlers/zones.go + zone/rtypes/*.go).
- The spec's
RecordName parameter even claimed relative names are accepted — they are not for PATCH/DELETE.
- Effect: asymmetric addressing (relative on POST/read, FQDN on PATCH/DELETE) and a 5xx for what is a client input error.
Proposed solution
Small (done now): make the docs truthful for v1
MXRecordPayload + examples → priority + host (matches code & read).
RecordName description → PATCH/DELETE require FQDN owner (apex = the zone itself); relative is POST/body-only.
- Document that POST auto-creates the zone and that zones are auto-signed (DNSSEC) — intended behaviors that were undocumented.
Big (future, under /api/v2): fix it correctly
Add an additive /api/v2/... route group with a thin translation layer; leave zone/rtypes/*, storage/WAL and DNS serving untouched:
- Names: v2 PATCH/DELETE accept the same owner form as POST/read (relative +
@); build the FQDN in the handler. Return 400 (not 500) on bad input.
- MX: adopt RFC names in v2 — request/response
{preference, exchange} mapped to the internal {priority, host}, so v2 is read/write symmetric and RFC-faithful. Other types already align (SRV priority/weight/port/target, CNAME target, NS ns, TXT text).
- Ship a v2 section in
docs/api/openapi.yaml.
Estimated effort: small–moderate, mostly additive (routes + a translation shim + v2 spec); no changes to the storage/serving layer.
Docs
docs/api/openapi.yaml has been updated to reflect the current v1 behavior described above.
Summary
Two inconsistencies in the admin HTTP API (record handling) between the OpenAPI spec, the actual code, and DNS conventions. Surfaced while building the solutrix-api go53 integration. The OpenAPI docs have been updated to describe the current v1 behavior truthfully; this issue tracks the proper fix under a future
/api/v2.Problem
1. MX payload field names
zone/rtypes/mx.go) reads/writes JSON fieldspriority+host, and the read responses return the same. Internally/serving is already RFC-correct (dns.MX{Preference, Mx}).MXRecordPayload, examples) instead documentedpreference+mx, which matches neither the code nor the read output. (RFC 1035 actually calls thesepreference+exchange.)500 "MXRecord expects field 'host'".2. Owner-name form differs between POST and PATCH/DELETE
POST /api/zones/{zone}/records/{rrtype}takes the ownernamerelative in the body (www,@) and works.PATCH/DELETE /api/zones/{zone}/records/{rrtype}/{name}pass the path{name}straight tortype.Delete()→internal.SplitName()which requires an FQDN; a relative name fails witherrors.New("invalid host format")returned as HTTP 500 (api/handlers/zones.go+zone/rtypes/*.go).RecordNameparameter even claimed relative names are accepted — they are not for PATCH/DELETE.Proposed solution
Small (done now): make the docs truthful for v1
MXRecordPayload+ examples →priority+host(matches code & read).RecordNamedescription → PATCH/DELETE require FQDN owner (apex = the zone itself); relative is POST/body-only.Big (future, under
/api/v2): fix it correctlyAdd an additive
/api/v2/...route group with a thin translation layer; leavezone/rtypes/*, storage/WAL and DNS serving untouched:@); build the FQDN in the handler. Return400(not500) on bad input.{preference, exchange}mapped to the internal{priority, host}, so v2 is read/write symmetric and RFC-faithful. Other types already align (SRVpriority/weight/port/target, CNAMEtarget, NSns, TXTtext).docs/api/openapi.yaml.Estimated effort: small–moderate, mostly additive (routes + a translation shim + v2 spec); no changes to the storage/serving layer.
Docs
docs/api/openapi.yamlhas been updated to reflect the current v1 behavior described above.