ingester
The ingester crate reads paginated APIs and makes an async stream of parsed
items.
You tell the crate two things:
- The request that it must send next.
- The procedure that parses each response into items.
The crate then does the work. It sends each request through an HTTP client
that you can replace. It obeys a rate limit that you can configure. It gives
the parsed items to you as a futures::Stream.
Your endpoint sees the last response before it makes the next request. Thus pagination with cursors, with tokens, or with a page count in the response body is possible.
Example
This example gets all the front-page story IDs from the Hacker News Algolia API. The endpoint gets the page count from the first response.
use ;
async
The collect() method collects all the items into a Vec. As an
alternative, use into_stream() to get each item when it arrives. If an
error occurs, the stream gives one Err item and then stops.
Operation
Implement the Endpoint trait. The trait has two methods:
next_request(&mut self, last: Option<&Response>) -> Option<Request>— make the next request. Thelastparameter contains the previous response. On the first call,lastisNone. For cursor pagination, read the cursor from the last response body. For a page counter, keep the counter inself. ReturnNoneto stop.parse(&self, response: &Response) -> Result<Vec<Item>, Error>— parse a response into zero or more items.
The ingest(endpoint) function makes an Ingester with the default
configuration. The default configuration is a reqwest HTTP client and no
rate limit. Use with_client and with_rate_limit to change the
configuration:
let ingester = ingest
.with_rate_limit // governor feature
.with_client;
Rate limits
Enable the governor feature to use a governor rate limiter. This
example permits a maximum of 2 requests each second:
use NonZeroU32;
use Quota;
use RateLimit;
let stories = ingest
.with_rate_limit
.collect
.await?;
Custom backends
The HTTP client and the rate limiter are traits. You can supply your own implementations. Some examples are:
- A different HTTP library.
- A rate limiter that your full application shares.
- A mock client for tests.
Implement ingester::client::Backend for an HTTP client. Implement
ingester::rate_limit::Backend for a rate limiter. Give the backend
directly to Ingester::new, with_client, or with_rate_limit. The crate
wraps the backend for you.
let items = new
.collect
.await?;
Feature flags
| Feature | Default | Effect |
|---|---|---|
reqwest |
yes | The default HTTP client backend and the ingest() function |
governor |
no | governor rate limiters as RateLimit backends, from_quota |
If you set default-features = false, the crate contains no HTTP client.
You must then supply your own client::Backend.
License
- MIT license (LICENSE)