Return objects instead of enums in RESTful APIs

A question that came up at work recently was, “should we return enums as ints or strings”?

The client-side team shouted that they prefer strings please, rather than “magic” ints.

I’m not a fan of strings, because then the client code becomes tightly coupled to those string values and you’ll see code like this in the clients:

if (customer.type == "goldCustomer") {
  // do something
}

Or, the clients need to have silly display code to make the string enum pretty, like this:

switch (customer.type) {
  case 'goldCustomer': return 'Gold customer';
  case 'silverCustomer': return 'Silver customer';
}

Occasionally these string enums might need to be renamed, e.g.
– one of the values isn’t correct because the business actually calls it something different, so it is confusing.

– there is a typo in the enum string, e.g. “goldCustomre”

But if you’re returning enums as strings, you can’t change any of the values, because renaming the string is a breaking API change which will break all the callers.

A more robust and loosely-coupled approach is to return an object instead, e.g.

"customer": {
  "type": {
    "id": 1,
    "displayName": "Gold customer"
  }
}

The client code then becomes:

if (customer.type.id == 1) {
  // do something
}

Which… I must admit, is a bit sucky and a bit “magic”. Hmm. I need to think about this a bit more…

I suppose the clients could define the enums somewhere in their logic, i.e.

enum CustomerType {
  Gold = 1,
  Silver,
}

if (customer.type.id == CustomerType.Gold) {
  // do something
}

At least, the switch statement in the client code above can be replaced with:

return customer.type.displayName

If the client needs all the values of your enum, e.g. for a select list, it can also be helpful to define the enums in a resource, e.g.

GET /customerTypes, which returns:

{
  customerTypes: [
    {
      "id": 1,
      "displayName": "Gold customer"
    },
    {
      "id": 2,
      "displayName": "Silver customer"
    }
  ]
}
Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s