Вернуть несколько ресурсов в вызове REST - PullRequest
0 голосов
/ 28 ноября 2018

Я предоставляю доступ к конечной точке REST, где вычисляются некоторые агрегаты.Допустим, модель выглядит следующим образом:

Покупка:

  • сумма: потраченная сумма
  • группа: одна из ЭЛЕКТРОНИКИ, ПИЩИ, МЕБЕЛИ, ...
  • дата: дата покупки

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

{
  "ELECTRONICS": [{"week": "2018WK1", "amount": 1000.0}, ...],
  "FOOD": [{"week": "2018WK1", "amount": 2000.0}, ...],
  "FURNITURE": [{"week": "2018WK1", "amount": 3000.0}, ...],
  ...
}

Некоторые замечания:

  • количество групп заранее неизвестно (зависит от хранимых данных)
  • , так как это вычисленные данные, я хотел бы вернуть все это в одном запросе, вместо того, чтобы делать агрегаты для каждой из групп в отдельных запросах

URL-адрес длязапрос будет выглядеть примерно так: /api/weekly_purchases/2018

Как я могу предложить такого рода ресурсы в REST API?

Ответы [ 2 ]

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

Как уже упоминалось в моем первоначальном комментарии или VoiceOfUnreason, те же методы, которые применяются к веб-браузеру, применяются к любой модели взаимодействия, используемой приложениями, которые следуют принципам архитектуры REST.Как также упоминалось VoiceOfUnreason, клиент первоначально запрашивал некоторое состояние, возвращаемое из точки входа, то есть https://api.acme.com, который будет возвращать набор ссылок, которые клиент может использовать для выполнения своей задачи.Чтобы клиент определил, какой URL вызывать, ответ должен дать значащему имени URI (имя отношения ссылки).IANA поддерживает список уже указанных имен отношений ссылок , которые вы должны использовать, если это возможно, или определять свое собственное в других стандартах.В соответствии с Fielding спецификация типов медиа и связей между ссылками является одной из самых важных вещей, которую нужно сделать при разработке архитектуры RESTful.

Для простоты я использую упрощенный HAL-Синтаксис JSON во всем примере.

{
  ...
  "_links": {
    "self": {
      "href": "https://api.acme.com"
    },
    ...
    "archives": {
      "href": "https://api.acme.com/weekly_purchases"
    },
    ...
  }
}

Согласно спецификации HTML 5 archives

указывает, что указанный документ описывает коллекциюзаписей, документов или других материалов, представляющих исторический интерес

Таким образом, имя отношения ссылки описывает назначение URI, которое клиент может использовать, если он заинтересован в извлечении коллекции исторических записей.Клиенту не обязательно знать точный URI, поскольку он узнает его, просто следуя целевому элементу href отношения ссылки.Это позволяет серверу в любое время изменять свою внутреннюю структуру URI, не прерывая работу клиентов.

При достижении целевого URI archives клиент пока не будет точно знать, как должны быть получены фактические данные в качествеURI и имя отношения ссылки являются общими.Но сервер проведет клиента через его задачу.Ответ на вызов вышеупомянутого целевого URI может возвращать следующее содержимое:

{
  "year": [
    "2018":  {
      "_links": {
        "chapter": {
          "href": "https://api.acme.com/weekly_purchases/2018"
        }
      }
    },
    "2017": {
      "_links": {
        "chapter": {
          "href": "https://api.acme.com/weekly_purchases/2017"
        }
      }
    },
    ...
    "2014": {
      "_links": {
        "chapter": {
          "href": "https://api.acme.com/weekly_purchases/2014"
        }
      }
    }
  ],
  "_links": {
    "self": {
      "href": "https://api.acme.com/weekly_purchases"
    },
    "first": {
      "href": "https://api.acme.com/weekly_purchases"
    },
    "next": {
      "href": "https://api.acme.com/weekly_purchases?p=1"
    },
    "last": {
      "href": "https://api.acme.com/weekly_purchases?p=3"
    },
    "current": {
      "href": "https://api.acme.com/weekly_purchases"
    }
  }
}

Этот ответ в основном учит клиента только тому, что доступно несколько лет, и клиент должен решить, какой год с/ он заинтересован в вызове этого URI для выполнения своей задачи.Отношение ссылки next, last и first указывает на то, что доступно несколько страниц, поскольку возвращается только 5 лет на страницу.Имя отношения ссылки current всегда будет указывать на самую последнюю запись в коллекции, которая является начальной страницей (или первой страницей) ресурса коллекции.Обратите внимание, как несколько разных имен связей могут указывать на один и тот же URI.Иногда не совсем понятно, какие имена отношений ссылок использовать, поскольку их семантика частично перекрывается.Это всего лишь пример того, что можно сделать с именами отношений ссылок.

Теперь клиент может дополнительно перейти к покупкам, совершенным в 2018 году, перейдя по ссылке на главу для 2018. Ответ на вызов этого URI теперь можетВыглядит так:

{
  "purchase": [
    "W1": {
      "sum": 1263.59,
      "currency": "Euro",
      "_links": {
        "about": {
          "href": "https://api.acme.com/weekly_purchases/2018/1"
        }
      }
    },
    "W2": {
      "sum": 569.32,
      "currency": "Euro",
      "_links": {
        "about": {
          "href": "https://api.acme.com/weekly_purchases/2018/2"
        }
      }
    },
    ...
    "W48": {
      "sum": 72.98,
      "currency": "Euro",
      "_links": {
        "about": {
          "href": "https://api.acme.com/weekly_purchases/2018/48"
        }
      }
    },
    "current": {
      "sum": 72.98,
      "currency": "Euro",
      "_links": {
        "about": {
          "href": "https://api.acme.com/weekly_purchases/2018/48"
        }
      }
    }
  ],
  "_links": {
    "index": {
      "href": "https://api.acme.com/weekly_purchases"
    },
    "self": {
      "href": "https://api.acme.com/weekly_purchases/2018"
    },
    "current": {
      "href": "https://api.acme.com/weekly_purchases/2018"
    },
    "prev": {
      "href": "https://api.acme.com/weekly_purchases/2017"
    },
    "prev-archive": {
      "href": "https://api.acme.com/weekly_purchases/2017"
    },
    "first": {
      "href": "https://api.acme.com/weekly_purchases/2000"
    }
  }
}

Вы можете добавить контент здесь к еженедельной сводке или скрыть его в будущем, перейдя по ссылке about, только если клиенты действительно заинтересованы в таких деталях.

Обратите внимание: поскольку weekly_purchases - это просто строка, не имеющая значения для клиента, она на самом деле не знает, что это значит.Поэтому вы также можете переименовать его в purchase-archive или что-то в этом роде и представить клиенту дополнительный выбор и позволить клиенту определить, хочет ли он еженедельную, ежемесячную или общую сводку за этот год.

REST - это предоставление выбора клиенту и обучение его тому, для чего предназначен фактический выбор.Одной из целей, которую пытается решить архитектура RESTful, является жесткая связь между клиентами и серверами, которая препятствует свободному развитию последнего и разрыву первых, если последний неожиданно изменится.Такое разделение работает только в том случае, если для повышения вероятности взаимодействия используются определенные стандарты.Обычно внеполосная информация (ранее существовавшие знания об API и о том, как с ним взаимодействовать) ведет к взаимосвязи.Даже Fielding заявил, что некоторые предварительные знания необходимы, но не кодируются непосредственно в приложение, а должны повторно использовать определенные стандарты, такие как четко определенные и стабильные типы носителей и имена связей.

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

Возврат нескольких ресурсов в вызове REST

Как бы вы сделали это как веб-страницу?

Где-то на вашем веб-сайте будет ссылка с текстом "резюме этой недели "(или что-то подходящее на языке вашего домена).Если пользователь щелкнет эту ссылку, браузер выполнит GET для одного URL-адреса, который перейдет на сервер, объединит все данные вместе и вернет результат.

Так что же делать?

REST не заботится о написании URI (браузер не пытается интерпретировать URL, за исключением очень поверхностных общих способов), поэтому /api/weekly_purchases/2018 - это отлично .

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

...