TIL #5: Representing Response Object in REST API

I was thinking what is the best way to represent response object in REST API. So, I started thinking about all the things response object should provide to work effectively. Below is the list of things I want my response object to have:

  1. A single object structure to handle both successful and error scenarios
  2. Ability to handle multiple types of objects
  3. Ability to easily figure out if request failed or succeeded
  4. Store the error code and error message

The code in this post uses Java as the language of choice. As I use Spring Boot to build REST APIs so Jackson is the default JSON serialisation library.

The code below shows the ApiResponse object that captures both the success and error payload.

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonValue;

public final class ApiResponse<T> {

    private ErrorResponse error;
    private T data;
    private Status status;

    private ApiResponse(Status status, ErrorResponse error) {
        this.error = error;
        this.status = status;
    }

    private ApiResponse(Status status, T data) {
        this.data = data;
        this.status = status;
    }

    @JsonCreator
    public static <T> ApiResponse<T> success(
            @JsonProperty("status") Status status,
            @JsonProperty("data") T data) {
        return new ApiResponse<>(status, data);
    }

    @JsonCreator
    public static <T> ApiResponse<T> error(
            @JsonProperty("status") Status status,
            @JsonProperty("error") ErrorResponse error) {
        return new ApiResponse<>(status, error);
    }

    public enum Status {
        SUCCESS("success"), ERROR("error");

        private final String status;

        Status(String status) {
            this.status = status;
        }

        @JsonValue
        public String getStatus() {
            return this.status;
        }
    }

    public ErrorResponse getError() {
        return this.error;
    }

    public T getData() {
        return this.data;
    }

    public Status getStatus() {
        return this.status;
    }
}

The key points in the class shown above are:

  1. Status enum will hold the status of the request. User can just look at this request to figure out whether request succeeded or failed.
  2. The class is generic so it can be used to store any type of object in the data.
  3. User can get more details about the error from the error object.

The ErrorResponse class is shown below.

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

public final class ErrorResponse {
    public final String code;
    public final String message;

    @JsonCreator
    public ErrorResponse(
            @JsonProperty("code") String code,
            @JsonProperty("message") String message) {
        this.code = code;
        this.message = message;
    }
}

The ErrorResponse class has two fields code and message. The code can be HTTP code or any business specific code. The message variable gives details about the error.

I found the above response classes work great for the REST APIs that I recently built.

Example of successful response is shown below.

{
    "status": "success",
    "data": {
        "task": "Write a post",
        "taskStatus":"in_progress",
        "tags":["writing"]
    }
}

Example of failure response is show below.

{
    "status": "error",
    "error": {
        "code" "409",
         "message" : "User with username xyz already exists"
    }
}

One thing that you should ensure is that your JSON serialisation library exclude null values. For example, in case of error scenario you don’t want data field to be null. If you are using Spring Boot, you can instruct Jackson to exclude null fields by specifying a property shown below.

spring.jackson.default-property-inclusion=NON_NULL

If you are using Java 8 or Google’s Gauva and want to exclude Optional type as well then you should use NON_ABSENT value.

spring.jackson.default-property-inclusion=NON_ABSENT
Advertisements

Keeping Spring Boot Powered REST API Request and Response Objects Minimal

I am a big fan of Spring Boot. It is my preferred choice for building REST APIs in Java. It takes less than 5 minutes(given that you have Maven dependencies on your local machine) to get started with Spring Boot thanks to its auto configuration. In this blog, I will talk about a specific aspect of building REST API with Spring Boot. We will look at the request and response objects. The request object that you receive during the HTTP POST request and response object that you send in the response of HTTP GET request. I will discuss how you can keep these request and response objects to the bare minimum so that we can avoid writing and maintaining useless getters and setters.

Read More »

Building A Lightweight Scala REST API Client with OkHttp

Welcome to the sixth blog of 52-technologies-in-2016 blog series. In this blog, we will learn how to write Scala REST API client for Medium’s REST API using OkHttp library. REST APIs have become a standard method of communication between two devices over a network. Most applications expose their REST API that developers can use to get work with an application programmatically. For example, if I have to build a realtime opinion mining application then I can use Twitter or Facebook REST APIs to get hold of their data and build my application. To work with an application REST APIs, you either can write your own client or you can use one of the language specific client provided by the application. Last few weeks, I have started using Medium for posting non-technical blogs. Medium is a blog publishing platform created by Twitter co-founder Evan Williams. Evan Williams is the same guy who earlier created Blogger, which was bought by Google in 2003.

Medium exposed their REST API to the external world last year. The API is simple and allows you to do operations like submitting a post, getting details of the authenticated user, getting publications for a user, etc. You can read about Medium API documentation in their Github repository. Medium officially provides REST API clients for Node.js, Python, and Go programming languages. I couldn’t find Scala client for Medium REST API so I decided to write my own client using OkHttp.

You can read the full blog here.

Day 23: TimelineJS–Build Beautiful Timelines

Today it took me a lot of time to find the right topic that I was comfortable with. I started with brain, then looked at Twitter Server, but finally I zeroed down on TimelineJS. So, today for the 30 day challenge, we will learn how to build a beautiful timeline for this blog series using TimelineJS. Read the full blog here https://www.openshift.com/blogs/day-23-timelinejs-build-beautiful-timelines

Day 13: DropWizard–The Awesome Java REST Server Stack

I have mainly been a Java guy throughout my 8 years as a software developer. For most of the applications I have written, I used the Spring framework or Java EE. Lately, I am spending time learning web development in Python, and one thing that has impressed me a lot is the Flask framework. The Flask framework is a micro-framework which makes it very easy to write REST backends. Today for my 30 day challenge, I decided to find a Java alternative to Python’s Flask framework. After doing some research, I discovered that the DropWizard framework can help me achieve the same productivity as the Flask framework. In this blog, we will learn how to build a RESTful Java MongoDB application using DropWizard. Read the full blog here https://www.openshift.com/blogs/day-13-dropwizard-the-awesome-java-rest-server-stack