Nếu bạn chán với việc tạo ra 1 đống callback khi code , thì mình sẽ giới thiệu cho các bạn :
Cách viết hàm get , post dùng cho tất cả mọi request !
Mình sẽ lấy dữ liệu về dưới dạng JsonElement và dùng JsonParser để parser ra object mình cần !

1. HttpClient


public interface HttpClient {
    @POST("{api}/{sub}")
    Call<JsonElement> postRequest(@Path("api") String api, @Path("sub") String sub,
                                  @Body JsonElement jsonData);
    @GET("{api}")
    Call<JsonElement> getRequest(@Path("api") String api, @Body JsonElement jsonData);
    enum Method {
        POST,
        GET
    }

    enum Api {
        LOGIN("login"),
        EVENTS("events");
       
        private String mValues;

        Api(String values) {
            mValues = values;
        }

        public String getValues() {
            return mValues;
        }
    }

    enum Sub {
        NONE(""),
        JOIN_EVENT_DAY("checkin");
        private String mValues;

        Sub(String values) {
            mValues = values;
        }

        public String getValues() {
            return mValues;
        }
    }

2. HttpRequest

2.1.

public class HttpRequest {
    private static final String BASE_URL = "url api của bạn";
    private static final String TAG = "HttpRequest";
    private static final int READ_TIMEOUT = 5;
    private static final int REQUEST_TIMEOUT = 2;
    private static Retrofit sInstance;
    private static HttpClient sService;
    private static HttpRequest sHttpRequest;

    public static HttpRequest sharedInstance() {
        if (sHttpRequest == null) {
            sHttpRequest = new HttpRequest();
        }
        return sHttpRequest;
    }

    private static Retrofit getRetrofit() {
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor)
            .connectTimeout(REQUEST_TIMEOUT, TimeUnit.SECONDS)
            .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
            .build();
        if (sInstance == null) {
            sInstance = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .client(client)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        }
        return sInstance;
    }

    private static HttpClient getHttpClient() {
        if (sService == null) {
            sService = getRetrofit().create(HttpClient.class);
        }
        return sService;
    }

    public void request(HttpClient.Method method, HttpClient.Api api, HttpClient.Sub sub,
                        JsonElement jsonData, Callback<JsonElement> callback) {
        switch (method) {
            case POST:
                getHttpClient().postRequest(api.getValues(), sub.getValues(), jsonData)
                    .enqueue(callback);
                break;
            case GET:
                getHttpClient().getRequest(api.getValues(), jsonData).enqueue(callback);
                break;
            default:
                break;
        }
    }

2.2. Thêm 1 function default

 public void request(HttpClient.Method method, HttpClient.Api api, JsonElement jsonData, Callback<JsonElement> callback) {
 request(method, api, Sub.NONE, jsonData, callback);
                        }

3. Cách dùng

Map<String, Object> params = new HashMap<>();
        params.put(Constant.KEY_REQUEST_TYPE,
            HttpClient.TypeLogin.TYPE_EMAIL.getValues());
        params.put(Constant.KEY_REQUEST_LOCALE, LanguageUtil.getLanguage());
        UserLoginEmail userLoginEmail = new UserLoginEmail().create(mEmail, mPassword);
        params.put(Constant.KEY_REQUEST_USER, userLoginEmail);
        HttpRequest.sharedInstance().request(HttpClient.Method.POST,
            HttpClient.Api.LOGIN, HttpClient.Sub.NONE,
            JsonParser.fromJsonElement(params), new Callback<JsonElement>() {
                @Override
                public void onResponse(Call<JsonElement> call,
                                       Response<JsonElement> response) {
                    JsonElement body = response.body();
                    if (body != null && body.isJsonObject()) {
                        String json = body.getAsJsonObject().toString();
                      LoginResponse loginResponse = JsonParser.fromJson(json, LoginResponse.class);
                    // TODO: 23/01/2017 
                    }
                }

                @Override
                public void onFailure(Call<JsonElement> call, Throwable t) {
                    mProgressDialog.dismiss();
                }
            }
        );

4. JsonParser

public class JsonParser {
    private static JsonSerializer<Date> serializerDate = new JsonSerializer<Date>() {
        @Override
        public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext
            context) {
            return src == null ? null : new JsonPrimitive(TimeUnit.SECONDS.toMillis(src.getTime()));
        }
    };
    private static JsonDeserializer<Date> deserializerDate = new JsonDeserializer<Date>() {
        @Override
        public Date deserialize(JsonElement json, Type typeOfT,
                                JsonDeserializationContext context) throws JsonParseException {
            return json == null ? null : new Date(TimeUnit.SECONDS.toMillis(json.getAsLong()));
        }
    };

    public static String toJson(Object object) {
        return new Gson().toJson(object);
    }

    public static JsonElement toJsonElement(Object object) {
        return new Gson().toJsonTree(object);
    }

    public static <Object> Object fromJson(String stringJson, Class<Object> classOfT)
        throws JSONException {
        JSONObject object = (JSONObject) new JSONTokener(stringJson).nextValue();
        Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, serializerDate)
            .registerTypeAdapter(Date.class, deserializerDate)
            .create();
        return object != null ? gson.fromJson(stringJson, classOfT) : null;
    }

    public static JsonElement fromJsonElement(Map<String, Object> params) {
        JsonElement jsonData = null;
        try {
            jsonData =
                JsonParser.fromJson(JsonParser.toJson(params), JsonElement.class);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return jsonData;
    }
}

5. Constant

public class Constant {
    // key request
    public static final String KEY_REQUEST_TYPE = "type";
    public static final String KEY_REQUEST_USER = "user";
    public static final String KEY_REQUEST_EMAIL = "email";
    public static final String KEY_REQUEST_PASSWORD = "password";
    public static final String KEY_REQUEST_LOCALE = "locale";
    }

6. UserLoginEmail

public class UserLoginEmail {
    @SerializedName("email")
    private String mEmail;
    @SerializedName("password")
    private String mPassword;

    public UserLoginEmail create(String email, String password) {
        mEmail = email;
        mPassword = password;
        return this;
    }

    public String getEmail() {
        return mEmail;
    }

    public String getPassword() {
        return mPassword;
    }
}

7. LoginResponse

public class LoginResponse extends BaseResponseModel {
    @SerializedName("message")
    private String mMessage;
    @SerializedName("access_token")
    private String mAccessToken;

    public String getMessage() {
        return mMessage;
    }

    public String getAccessToken() {
        return mAccessToken;
    }
}

8 . Thêm header

private static Retrofit getRetrofit() {
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient client = new OkHttpClient.Builder()
            .addNetworkInterceptor(new Interceptor() {
                @Override
                public Response intercept(Chain chain) throws IOException {
                    Request.Builder requestBuilder = chain.request().newBuilder()
                        .addHeader(AUTHORIZATION, BASE_AUTHORIZATION);
                    return chain.proceed(requestBuilder.build());
                }
            })
            .addInterceptor(interceptor)
            .connectTimeout(REQUEST_TIMEOUT, TimeUnit.SECONDS)
            .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
            .build();
        if (sInstance == null) {
            sInstance = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .client(client)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        }
        return sInstance;
    }