У меня есть еще один вопрос по API, который, кажется, лучше поставить в отдельном вопросе, чем тот, который я только что опубликовал.Я пытаюсь преобразовать веб-приложение, работающее на Codeigniter, в бэкэнд в стиле отдыха.Я новичок в остальном API, и я просто пытаюсь понять, как это будет работать.
Кроме того, я знаю о библиотеке rest-server , котораякажется, что все используют, но я не заинтересован в том, чтобы идти по этому пути, поэтому я ищу ответы, не относящиеся к этой библиотеке.
У меня есть таблица users и таблица внешних ссылокдля пользователей мест.В настоящее время с моим подтверждением концепции API я могу позвонить api/users?fields=first_name,last_name,email
и получить правильный ответ.Однако, если бы я смотрел на это как на json, у пользователя был бы объект местоположений со всеми местоположениями, к которым у него есть доступ.Я попытался включить этот запрос в свою модель, но если бы я использовал api/users?fields=locations
, я получаю ошибку, потому что местоположения не являются полями в моей таблице пользователей.
Я знаю, что мог бы поместить некоторую логику вместо, чтобы проанализировать эту строку и определить, какие поля идут в какую таблицу, но кажется, что должно быть более элегантное решение.
Кроме того, в настоящее время я могу сделать что-то вроде api/users?last_name=bezos
, которое будет искать пользователей, где фамилия Безос.Но как правильно разработать API для того, чтобы вы могли сказать last_name=bezos
ИЛИ last_name=gates
?Это будут 2 вызова API или вы можете структурировать строки запроса там, где это будет возможно?если так, как это должно выглядеть?Есть ли набор стандартов, на которые я должен смотреть?
public function read($id = NULL, $params)
{
$filters = ($params['filters']) ?? NULL;
$this->db->select($params['select_fields']);
$this->db->from(TBL_USERS);
if($filters)
{
foreach($filters as $col => $val)
{
$this->db->where('UPPER(' . $col . ')', strtoupper($val));
}
}
if($id)
{
$this->db->where('user_id', $id);
}
$result = $this->db->get()->result_array();
return $result;
}
Вот оставшаяся часть кода контроллера для справки.
Я использую маршруты, чтобы убедиться, что URL-адреса настроены правильно:
$route['users'] = 'users/index';
$route['users/(:any)'] = 'users/index';
Оттуда мой метод конструктора базового контроллера создает несколько классов:
$this->request = new stdClass()
$this->api = new stdClass();
$this->request->http_method =($this->input->method()) ?? 'get';
$this->request->resource = $this->uri->segment(1);
Я поместил в базовый контроллер метод индекса, который обрабатывает первоначальный запрос:
function index()
{
$method = $this->route_request();
$id = ($this->uri->segment(2)) ?? NULL;
if(method_exists($this, $method))
{
$this->{$method}($id);
}
else
{
$this->output->set_status_header(404);
exit;
}
}
запрос направляется в соответствующий метод класса:
protected function route_request()
{
$this->api->method = $this->request->resource . '_';
switch($this->request->http_method)
{
case 'get':
$this->parse_params();
$this->api->method .= $this->request->http_method;
break;
case 'post':
echo 'post';
break;
case 'patch':
echo 'patch';
break;
case 'delete':
echo 'delete';
break;
}
return $this->api->method;
}
И этот метод анализирует строки запроса для получения запросов:
protected function parse_params()
{
$input = $this->input->get();
$this->request->params['select_fields'] = ($input['fields']) ?? '*';
unset($input['fields']);
if(sizeOf($input) > 0)
{
$this->request->params['filters'] = $input;
}
}
Все вышеперечисленные результаты при этом вызывают:
function users_get($id)
{
$response = $this->Users_model->read($id, $this->request->params);
echo json_encode($response);
}