public static function selectByRequest(array $criteria = [], array $options = [])
    {
        $criteria = static::cleanCriteria($criteria);
        $pk = static::getPrimaryKeyStatic();
        $selection = array_get($criteria, 'select');
        if (empty($selection)) {
            $selection = ['*'];
        }

        $related = array_get($options, ApiOptions::RELATED, []);
        if (is_string($related)) {
            $related = explode(',', $related);
        }

        $condition = array_get($criteria, 'condition');
        if (!empty($condition)) {
            $params = array_get($criteria, 'params');
            $builder = static::whereRaw($condition, $params)->with($related);
        } else {
            $builder = static::with($related);
        }

        if (!empty($limit = array_get($criteria, 'limit'))) {
            $builder->take($limit);
        }

        if (!empty($offset = array_get($criteria, 'offset'))) {
            $builder->skip($offset);
        }

        $orderBy = array_get($criteria, 'order', "$pk asc");
        $orders = explode(',', $orderBy);
        foreach ($orders as $order) {
            $order = trim($order);

            @list($column, $direction) = explode(' ', $order);
            if (empty($direction)) {
                $direction = 'ASC';
            }

            $builder = $builder->orderBy($column, $direction);
        }

        $groupBy = array_get($criteria, 'group');
        if (!empty($groupBy)) {
            $groups = explode(',', $groupBy);
            foreach ($groups as $group) {
                $builder = $builder->groupBy(trim($group));
            }
        }

        $response = $builder->get($selection);

        return static::cleanResult($response, array_get($criteria, 'select'));
    }