public final ApiResult genResult() {
    ApiRequest apiRequest = getRequest();
    ViewerContext viewerContext = genViewerContext(apiRequest);
    ControllerRequest controllerRequest = createControllerRequest(apiRequest);
    controllerRequest.setViewerContext(viewerContext);
    // TODO: this look not cool
    if (getRequireLoggedIn() && !viewerContext.isLoggedIn()) {
      return getError(controllerRequest, ErrorType.NOT_LOGGED_IN);
    }
    boolean isValidRequest = controllerRequest.isValid();
    if (!isValidRequest) {
      return getError(controllerRequest, ErrorType.INVALID_REQUEST);
    }
    try {
      ControllerResult controllerResult = genControllerResult(controllerRequest);
      return new ApiResult(controllerResult, controllerRequest.getCallback());
    } catch (Exception exception) {
      exception.printStackTrace();
      return getError(controllerRequest, ErrorType.UKNOWN_ERROR);
    }
  }