Guidelines on JSON responses for RESTful services

Sunit Parekh
4 min readApr 3, 2018

--

Now days RESTful API is followed heavily on most of the projects. Since it doesn’t prescribe every details, many times I have seen developers start following different ways of implement for similar patterns in API, leading to inconsistent API. So during initial stage of the project it is very important to discuss and define guidelines for RESTful APIs. In this article I am focusing on JSON response guidelines.

Responding success and failure

First question that comes in discussion is, How shall we craft response for success and failure? Different options are, Option 1) Use HTTP status codes conveying the status + json body in response payload Option 2) always return 200 and response payload to have status and data fields.

My take is use HTTP status code to convey the response status. And I prefer not to create envelope response but return requested object at top level JSON. And for errors return appropriate HTTP status code with more detailed error message and errors as JSON response.

SUCESS: GET single item, HTTP Response Code: 200
ERROR Conditions

Effective use of HTTP status code helps with leveraging HTTP caching and coding clients. Also it is important to discuss and decide which status code to use when.

List and search result type of responses

Next question comes up is, how to return list or search result like responses?
This is the heavily debatable and many times inconclusive topic for whole team to agree. Okay, what are the options? Option 1) use envelope style response, result includes count plus data, however for error conditions such as bad input or un-authorized request use appropriate HTTP status code Option 2) return only data with HTTP status code and use response headers for count fields Option 3) always return 200 and status in response body

My take, here I am divided between option 1 and 2. Still preferred option is Option 2, return only data and convey summary fields using headers. Another alternative to sending count field in response header is have separate count API. This is also useful many times as you need count only once.

Use of response header is key in the above example. Next-Page response header tells client that I have more data (next page) available. And such headers can be really useful for loading next pages on scroll.

However, when I look at API like elasticsearch I get convinced that Option 2 is also right. Choose one for the project and follow it.

JSON key (property/field name) naming convention

Now it’s time to get inside the JSON fields. What should be naming convention for fields? Options are 1) camelCase 2) snake_case 3) spinal-case for keys.

My choice here is Option 1) camelCase and that must be from my background as Java developer. I have seen equal use of snake_case as well, but very rare use of spinal-case.

Avoid using dot (.) in key names, as they conflict with the JSON path.

Handling NULL values

It’s time to look at, how to return NULL values? This is again another area of debate starts. Options are 1) Do not return NULL values 2) Return as null value.

I prefer Option 1) Do not return NULL values. However, question becomes tricky when value is object or array and it is empty. In that case empty {} or [] is valid JSON response.

I do not prefer null values as it can have side effects while parsing on client side. E.g. In JavaScript null has special meaning. Just be careful not to choose returning empty string (“”) which does not express as value doesn’t exists.

Date and DateTime responses

This one is most important, What should be format for date and datetime (timestamp) type of fields? Option here is ISO 8601 format returned as string. However, many time not knowing it, make developer to follow “default toString” or “self-made formats”. Most of the languages have default support for serializing and deserializing, date and datetime in ISO 8601 format.

// audit fields
{
"createdBy": "123456",
"createdAt": "2012-01-01T18:25:43.511Z",
"createdBy": "123456",
"createdAt": "2012-01-01T18:25:43.511Z",
}

Even if you choose to return datetime always in only one timezone such as UTC. I still recommend to choose ISO 8601 standard which includes timezone.

Multiline string values

Many times I need to send large multiline string as values e.g. Address. How do I pass multiline string value? Options are 1) as array of strings 2) base64 encoding.

Solution that worked for me is base64 encoding for values.

// multiple as array
{
"singleLine": "Some singleline String",
"multiline": ["Line one", "Line Two", "Line Three"]
}
// multiple as base64 encoded string
{
"singleLine": "Some singleline String",
"multiline": "TGluZSBvbmUKTGluZSBUd28KTGluZSBUaHJlZQ=="
}

Another example is to use base64url encoded query param for GET request providing search criteria as JSON. :-)

{ "name": "sunit", "office": "pune"}/* above search criteria parameters send in GET request param as base64url encoded *//search?query="eyAibmFtZSI6ICJzdW5pdCIsICJvZmZpY2UiOiAicHVuZSJ9"

Summary

And there are many more discussion and decisions to be made for JSON responses guidelines, such as,

  1. How to represent structural data? nested vs flatten
  2. Define standards for paginated results? (params and result both)
  3. Singular vs Plural Property Names?
  4. If needed, how would you version your API and how to return response with version info ?
  5. Think about more data types? e.g. Latitude/Longitude values

Point I would like to derive from this article is, at the beginning of the project collectively define guidelines for RESTful services for the project and write it down. Also keep it open for discussion and further amendments.

Another new trend to explore is GraphQL for building API that needs to be consumed by many discrete client needs.

--

--