REST API Design for Usability: Human-Readable Date Fields

An API with great Developer Experience (DX) returns responses as immediately understandable as possible, and one common and easily achieved usability feature is to include human-readable or “pretty” date or timestamp fields in JSON representations, in addition to the Unix Epoch timestamps preferred for machine consumption.

In a software project an API can be used by many kinds of technical people, from developers to QA to Product Owners, to test functionality or examine data. In many cases the timestamps on the data are valuable information, and reading them quickly can be very handy and boost productivity, for example to see how recent data is, if it is valid and sorted correctly, and so on.

The following example shows an updated-at field on a response with an added pretty version of the field:

GET /resources/1

{
  "id": 12345,
  "updatedAt": 1580778703,
  "updatedAtPretty": "Tue, 04 Feb 2020 01:11:43 GMT"
}

If using a specific format, we can also include ISO or something similar in the name, referring to the format:

{
  "id": 12345,
  "updatedAt": 1580778877,
  "updatedAtIso": "2020-02-04T01:14:37Z"
}

We could also use updatedAtIso8601 if using this specific readable format. Two other options for general human-readable date fields:

updatedAtReadable
updatedAtHuman

This extra field should not affect the response size much since all API responses should be gzipped.

However, if small size is very important we can always make the feature optional, so that the readable date is only added if a query string parameter is included. This post discusses this pattern in general. Such a request could look like the following:

GET /resources?prettyDates=true

Readable Versions of Other Types of API Fields

Dates and times are not the only kinds of data which could benefit from readable versions. If we have other kinds of human-readable fields, the parameter could control several fields in addition to just the readable date. Suppose we have a field called fileSizeReadable for example, to complement a field expressed in bytes. For a parameter controlling all human-readable fields we could use:

GET /resources?readable=true

GET /resources?human=true

To show a complete example, a default response:

GET /resources/1

{
  "id": 12345,
  "updatedAt": 1580778877,
  "fileSize": 95098036
}

The same call including the pretty fields:

GET /resources/1?human=true

{
  "id": 12345,
  "updatedAt": 1580778877,
  "updatedAtPretty": "2020-02-04T01:14:37Z",
  "fileSize": 95098036,
  "fileSizePretty": "138.3 MB"
}

 

Leave a Reply

Your email address will not be published. Required fields are marked *