The One True Response Format

It is simple.

In its simplest form:

{ "success":true, "messages": [] }

With messaging:

{ "success":true,
  "messages": [
     {"type":"info","text":"Took bottle down"},
     {"type":"success","text":"Bottle passed around"},
     {"type":"warning","text":"97 bottles remain on the wall"}
    ]
}

With error messaging:

{ "success":false,
  "messages":[
     {"type":"error","text":"1 bottle happened to fall!"}
    ]
}

The one true response format:

  • Uses the same structure for both successful and failed requests.
  • Makes success/failure explicit with a boolean inside the payload.

Other response formats blur success/failure across different places, some in the response payload, some external to it.

The one true response format:

  • Uses the same structure for zero, one, or more messages. Message type is per-message.

Many other response formats support just one message. Or assume all messages are error messages.

The one true response format:

  • Is extensible. You can add other keys to the response object itself, or to the messages.

Coercion: The one true response format requires a coercion layer in front of it, whose job is to coerce ANY response into a OTRF object. If the response is already an OTRF object, wonderful.

If the response is "4510164d4f3a005343004e430e1e1d0a524612171b0117", the coercion layer produces something like:

{ "success":false,
  "messages":[
     {"type":"error","text":"Something went quite wrong!"}
    ]
}

If the response is an http code 413, the output of the coercion layer might produce:

{ "success":false,
  "messages":[
     {"type":"error","text":"Payload too large"}
    ]
}

The coercion layer cares about the transport mechanism so the rest of your code doesn't have to.

The one true response format does not solve every application design problem. But it simplifies many. Think of it as a standard-guage rail system for data exchange.