Design System With Unique Response Code

Unique Code across system saves Developers time and API debugging time

Design System With Unique Response Code

This article is mainly targeted towards API developers or Developer Experience team members. Views may differ, happy to learn different views from others.

We are in a world where most of the development is API-driven. We are in a fast-paced world where we will need to find solutions quickly.

APIs are usually consumed at various places, it can be consumed by Mobile developers or Frontend web developers, or developers from other companies/organizations who integrate your products. In such a big scenario it is very important to design the API and also specifically API error code properly.

Consider the below API response which I got during creating a page on the website using POST Request. The API is well documented and the response is also correct as they have mentioned.

{
"status_code": "1",
"status_message": "failure",
"api_type": "page_addition",
"developer_message": "Page cannot be created"
}

Yes, this response looks neat JSON. But think of the developer who is handling when they are connecting on the other side.

The following are the mistake in the above response

  1. Here for sure developer_message is not a static string (it cannot be the same always), it can change due to grammar or it can change based on language. In big very organizations generally, the messages are most I18N (Internationalization). In the case in the future, if the response changes based on the preference language chosen by the admin of the account then it will be hard, and rework has to be done here.

  2. for status_message here the value is a failure, what type of failure, whether any authentication problem (yes sometimes some teams capture it inside the app and send with status code 200) or the problem is too many created in general or for that plan

  3. for status_code here the value is 1, such values are found across different APIs.

In case the developers at the other end have to capture the above error then they have to do two checks whether the status_message is failure and api_type is page_addition.

The proper fix for this is having a different unique status code. Something like

{ 
     "code": 18932, 
     "message": "Not able to create Page", 
     "error_message_code": "not_able_to_create_page",
    "api_type": "page_addition", 
}

Here in the above response, it is enough to check whether the code is 18932 or any other unique number. Even this will have some mistakes like readability is not proper or maintain the code of 18932 and status should be unique. But it's easier for teams who integrate with your product or during debugging the issue.

Whenever I mentor other junior developers I always ask them to have a unique list of response codes in the same file in some specific format. This will help in case we are going to write custom exception handling in Java or want to send a similar type of response to API invokers. Sharing a sample below, this can be improved still more based on the need but the core concept is to make sure errorCode is kept on the same file so duplication is avoided and easier to debug using call hierarchy (find usage in system)

class ResponseCode {
    public enum APIERRORCODE {
        NOT_ABLE_TO_CREATE_PAGE(18932, "page_addition", "not_able_to_create_page", "Not able to create Page"), // NO I18N
        PAGE_PUBLISHED(18933, "page_addition", "page_created", "Page Created At Site"); // NO I18N

        private final int uniqueErrorCode;
        private final String apiType;
        private final String uniqueErrorMessageCode;
        private final String errorMessage;

        APIERRORCODE(int errorCode, String apiTypeString, String errorMessageCode, String errorMessageStr) {
            uniqueErrorCode = errorCode;
            apiType = apiTypeString;
            uniqueErrorMessageCode = errorMessageCode;
            errorMessage = errorMessageStr;
        }

  public int getUniqueErrorCode(){
            return this.uniqueErrorCode;
        }

        public JSONObject getResponseObject() {
            JSONObject clientJSON = new JSONObject();
            try {
                clientJSON.put("code", this.uniqueErrorCode) // NO I18N
                        .put("api_type", this.apiType)  // NO I18N
                        .put("error_message_code", this.uniqueErrorMessageCode) // NO I18N
                        .put("message", this.errorMessage); // NO I18N

            } catch (Exception exceptionObject) {
                Logger.getLogger(this.getClass().getName(),exceptionObject.getMessage());
            }
            return clientJSON;
        }

    }
}

In case if you are going to use this Error message inside the system across different tiers I would strongly recommend you using the getter like getUniqueErrorCode to get the errorcode and process the things ahead. Strictly avoid using JSONObject between the internal method invocation if possible.