В этой статье я расскажу о том, как мы можем создавать запросы в Rust. Прежде чем мы начнем, пожалуйста, добавьте следующие зависимости в ваш файл cargo.toml.
Целью этого запроса является извлечение данных с веб-сайта asx с указанием названия компании. Более конкретно, мы будем использовать функцию прогнозирующего поиска ASX. Ниже будет указан URL-адрес нашего запроса.
Вот пример того, как выполняется запрос API, в котором “woolworths” является параметром поиска.
Если мы выйдем в Network, мы сможем увидеть фактический запрос API, в то же время мы сможем узнать, какиме заголовки есть у нашего запроса.
Вот как выглядит запрос curl!
Теперь, когда у нас есть все детали, необходимые для оформления запроса, давайте посмотрим на запрос crate reqwest. Reqwest - интересный пакет, особенно в том, что касается реализации функции синхронным и асинхронным способом. Основным отличительным фактором с точки зрения семантики является включение функции `blocking`. В то же время, почему это называется блокировкой? Ну, поскольку синхронный код, по сути, блокирует!
Предположим, мы должны сделать запрос, но получение ответа занимает у нас 2 секунды, синхронный код будет означать, что мы застреваем на этой строке кода на 2 секунды, пока не получим ответ, тогда как в асинхронном коде мы могли бы делать что-то еще в ожидании ответа, например, рендеринг веб-сайт, если пользователь нажимает на что-то. Вы же не хотите, чтобы веб-сайт отображался после того, как ваш запрос получит ответ через 2 секунды, не так ли?
Хотя вы могли бы привести доводы в пользу синхронного запроса. Как сказано в `reqwest crate`, “Для приложений, желающих выполнить всего несколько HTTP-запросов, `reqwest::blocking` API может быть более удобным”. Однако, с точки зрения удобства, это, скорее всего, говорит о том, насколько проще настроить синхронный запрос, чем асинхронный, и поскольку выполняется всего несколько запросов, это не соответствует варианту использования для выполнения асинхронных запросов. Чтобы добавить к этому, существует нечто, называемое синхронной связью, некоторым системам, возможно, придется придерживаться этого принципа проектирования, где он должен обрабатывать 1 запрос и 1 ответ в точном порядке, однако при асинхронной связи может быть множество запросов, и каждый из ответов может возвращаться в случайном порядке.
Однако в сегодняшнем уроке мы будем использовать асинхронный фреймворк!
В приведенном выше коде, как вы можете видеть, мы включили заголовки из запроса curl, используя `HeaderMap` из библиотеки `reqwest`. Для каждого нового запроса мы создаем новый экземпляр этого объекта (на самом деле нам это не обязательно, скорее всего, есть какие-то другие обходные пути) и отправляем наш запрос с нашим отформатированным url. Обратите внимание, как вы можете видеть, я добавил функцию ожидания, так что весь этот запрос должен занять не менее 5000 миллисекунд.
Первое, что может броситься вам в глаза, это то, что основная функция является асинхронной. Причина, по которой у нас это, кроется в макросе прямо над которым находится. `#[tokio::main]`. Взятый из документации reqwest, этот макрос, по сути, “помечает асинхронную функцию, которая должна выполняться выбранной средой выполнения. Этот макрос помогает настроить среду выполнения, не требуя от пользователя непосредственного использования среды выполнения или постороения.” В этом случае асинхронная функция ЯВЛЯЕТСЯ основной функцией, которая отличается от настройки в предыдущем примере.
Первые две строки здесь создают 2 фьючерса. ` tokio::join!` затем берет эти фьючерсы и выполняет их асинхронным образом. Таким образом, общее время, затраченное на эти 2 запроса, несмотря на то, что для возврата ответа обоим требуется не менее 5000 миллисекунд, составит .... около 6250 миллисекунд. Вот вывод результатов:
И, таким образом, на этом мой урок заканчивается!
Просто на случай, если всем интересно, как я все десериализовал:
Статья на list-site.