Самый простой способ реализовать фильтры нескольких параметров в REST API - PullRequest
0 голосов
/ 22 ноября 2018

В настоящее время я реализую RESTFUL API, который предоставляет конечные точки для взаимодействия с базой данных.

Я хочу реализовать фильтрацию в своем API, но мне нужно предоставить конечную точку, которая может обеспечить способ применения фильтрации к таблице с использованием всех столбцов таблицы.

Я нашел некоторыетакие шаблоны, как:

GET /api/ressource?param1=value1,param2=value2...paramN=valueN

param1, param2 ... param N - это столбцы моей таблицы и значения.

Я также нашел другой шаблон, который состоит из отправки объекта JSON, которыйпредставляет запрос.

Чтобы отфильтровать поле, просто добавьте это поле и его значение к запросу:

GET /app/items
{
  "items": [
    {
      "param1": "value1",
      "param2": "value",
      "param N": "value N"
    }
  ]
}

Я ищу лучшую практику для достижения этой цели.

Я использую EF Core с ASP.NET Core для реализации этого.

1 Ответ

0 голосов
/ 23 ноября 2018

Во-первых, будьте осторожны с фильтрацией всего.Основывайте доступные фильтры на потребностях пользователей и расширяйте их в зависимости от спроса.Меньше кода для написания, меньше сложности, меньше индексов на стороне БД, лучшая производительность.

Тем не менее, подход, который я использую для страниц со значительным количеством фильтров, заключается в использовании серверной части перечисления, где мойПоля критериев передаются обратно их значения перечисления (число), чтобы предоставить по запросу.Таким образом, поле фильтра будет содержать имя, значения по умолчанию или применимые значения и значение перечисления, которое будет использоваться при передаче введенного или выбранного значения обратно в поиск.Запрашивающий код создает объект JSON с примененными фильтрами и Base64 для отправки в запросе:

Т.е.

{
  p1: "Jake",
  p2: "8"
}

Строка запроса выглядит следующим образом: .../api/customer/search?filters=XHgde0023GRw....

На стороне сервера я извлекаю Base64, а затем анализирую его как Dictionary<string,string> для подачи на анализ фильтра.Например, учитывая, что критерии были для поиска ребенка по имени и возрасту:

// this is the search filter keys, these (int) values are passed to the search client for each filter field.
public enum FilterKeys
{
    None = 0,
    Name,
    Age,
    ParentName
}

public JsonResult Search(string filters)
{
    string filterJson = Encoding.UTF8.GetString(Convert.FromBase64String(filters));
    var filterData = JsonConvert.DeserializeObject<Dictionary<string, string>>(filterJson);

    using (var context = new TestDbContext())
    {
        var query = context.Children.AsQueryable();

        foreach (var filter in filterData)
            query = filterChildren(query, filter.Key, filter.Value);

        var results = query.ToList(); //example fetch.
        // TODO: Get the results, package up view models, and return...
    }
}

private IQueryable<Child> filterChildren(IQueryable<Child> query, string key, string value)
{
    var filterKey = parseFilterKey(key);
    if (filterKey == FilterKeys.None)
        return query;

    switch (filterKey)
    {
        case FilterKeys.Name:
            query = query.Where(x => x.Name == value);
            break;
        case FilterKeys.Age:
            DateTime birthDateStart = DateTime.Today.AddYears((int.Parse(value) + 1) * -1);
            DateTime birthDateEnd = birthDateStart.AddYears(1);
            query = query.Where(x => x.BirthDate <= birthDateEnd && x.BirthDate >= birthDateStart);
            break;
    }
    return query;
}

private FilterKeys parseFilterKey(string key)
{
    FilterKeys filterKey = FilterKeys.None;

    Enum.TryParse(key.Substring(1), out filterKey);
    return filterKey;
}

Вы можете использовать строки и константы, чтобы избежать анализа перечисления, однако я считаю, что перечисления читаемы и сохраняют отправленную полезную нагрузку внемного компактнее.Выше приведен упрощенный пример и, очевидно, требуется проверка ошибок.Код реализации для сложных условий фильтрации, таких как возраст до даты рождения, лучше подойдет как отдельный метод, но он должен дать вам некоторые идеи.Например, вы можете искать детей по имени, и / или возрасту, и / или имени родителя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...