Add RiotApi::new(impl Into<RiotApiConfig>), deprecate old constructors, update docs

- Adds `From<AsRef<[u8]>> for RiotApiConfig` for API keys for the above.
This commit is contained in:
Mingwei Samuel 2021-09-19 11:22:09 -07:00
parent 8f5d7327d1
commit 1a0ae872f5
7 changed files with 88 additions and 52 deletions

View file

@ -15,13 +15,13 @@ Riven's goals are _speed_, _reliability_, and _maintainability_. Riven handles r
Data structs and endpoints are automatically generated from the
[Riot API Reference](https://developer.riotgames.com/api-methods/) ([Swagger](http://www.mingweisamuel.com/riotapi-schema/tool/)).
## Design
# Design
* Fast, asynchronous, thread-safe.
* Automatically retries failed requests.
* Supports all endpoints, kept up-to-date using [riotapi-schema](https://github.com/MingweiSamuel/riotapi-schema).
## Usage
# Usage
```rust
use riven::RiotApi;
@ -32,7 +32,7 @@ let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(async {
// Create RiotApi instance from key string.
let api_key = std::env!("RGAPI_KEY"); // "RGAPI-01234567-89ab-cdef-0123-456789abcdef";
let riot_api = RiotApi::with_key(api_key);
let riot_api = RiotApi::new(api_key);
// Get summoner data.
let summoner = riot_api.summoner_v4()
@ -70,9 +70,14 @@ Output:
9) Irelia 46465 (5)
10) Vladimir 37176 (5)
```
### Feature Flags
The [`RiotApi` struct documentation](https://docs.rs/riven/latest/riven/struct.RiotApi.html)
contains additional usage information. The [tests](https://github.com/MingweiSamuel/Riven/tree/v/2.x.x/riven/tests)
and [example proxy](https://github.com/MingweiSamuel/Riven/tree/v/2.x.x/example/proxy)
provide more example usage.
#### Nightly vs Stable
## Feature Flags
### Nightly vs Stable
Enable the `nightly` feature to use nightly-only functionality. This enables
[nightly optimizations in the `parking_lot` crate](https://github.com/Amanieu/parking_lot#nightly-vs-stable).
@ -81,7 +86,7 @@ Enable the `nightly` feature to use nightly-only functionality. This enables
riven = { version = "...", features = [ "nightly" ] }
```
#### rustls
### rustls
Riven uses [reqwest](https://github.com/seanmonstar/reqwest) for making requests. By default, reqwest uses the native TLS library.
If you prefer using [rustls](https://github.com/ctz/rustls) you can do so by turning off the Riven default features
@ -93,11 +98,11 @@ riven = { version = "...", default-features = false, features = [ "rustls-tls" ]
Riven is additionally able to produce [tracing](https://docs.rs/tracing) spans for requests if the `tracing` feature is enabled. This feature is disabled by default.
### Docs
## Docs
[On docs.rs](https://docs.rs/riven/).
### Error Handling
## Error Handling
Riven returns either `Result<T>` or `Result<Option<T>>` within futures.
@ -116,12 +121,12 @@ diagnostic information, such as the source Reqwest error, the number of retries
attempted, and the Reqwest `Response` object.
You can configure the number of time Riven retries using
`RiotApiConfig::set_retries(...)` and the `RiotApi::with_config(config)`
`RiotApiConfig::set_retries(...)` and the `RiotApi::from_config(config)`
constructor. By default, Riven retries up to 3 times (4 requests total).
Some errors, such as 400 client errors, are not retried as they would
inevitably fail again.
### Semantic Versioning
## Semantic Versioning
This package follows semantic versioning to an extent. However, the Riot API
itself changes often and does not follow semantic versioning, which makes
@ -137,21 +142,22 @@ not the major version.
Parts of Riven that do not depend on Riot API changes do follow semantic
versioning.
### Additional Help
## Additional Help
Feel free to [make an issue](https://github.com/MingweiSamuel/Riven/issues/new)
if you are have any questions or trouble with Riven.
## Development
# Development
NodeJS is used to generate code for Riven. The
[`srcgen/`](https://github.com/MingweiSamuel/Riven/tree/v/2.x.x/riven/srcgen)
[`riven/srcgen`](https://github.com/MingweiSamuel/Riven/tree/v/2.x.x/riven/srcgen)
folder contains the code and [doT.js](https://olado.github.io/doT/index.html)
templates. `index.js` lists the JSON files downloaded and used to generate the
code.
To set up the srcgen, you will first need to install NodeJS. Then enter the
srcgen folder and run `npm ci` (or `npm install`) to install dependencies.
`riven/srcgen` folder and run `npm ci` (or `npm install`) to install
dependencies.
To run the srcgen use `node srcgen` from the main folder.
To run the srcgen use `node riven/srcgen` from the repository root.

View file

@ -1,8 +1,15 @@
# Riven Example Proxy
This is a simple example implementation of a Riot API proxy server using `hyper`. This adds the API key and forwards
requests to the Riot API, then returns and forwards responses back to the requester. It handles error cases but only
provides minimal failure information. HTTP requests will wait to complete when Riven is waiting on rate limits.
This is a simple example implementation of a Riot API proxy server using
[`hyper`](https://github.com/hyperium/hyper). This adds the API key and
forwards requests to the Riot API, then returns and forwards responses back to
the requester.
This can handle not just GET endpoints but also POST and PUT (and any others)
with bodies, however it does not handle RSO endpoints which require an
`Authorization` header parameter. This handles errors but provides only minimal
failure information. Rate limits are enforced, so requests will wait to complete
when Riven is at the rate limit.
Set `RGAPI_KEY` env var then run:
```bash

View file

@ -23,8 +23,7 @@ lazy_static! {
std::fs::read_to_string(path).ok()
})
.expect("Failed to find RGAPI_KEY env var or apikey.txt.");
RiotApi::with_config(RiotApiConfig::with_key(api_key.trim())
.preconfig_burst())
RiotApi::new(RiotApiConfig::with_key(api_key.trim()).preconfig_burst())
};
}

View file

@ -19,11 +19,11 @@ pub struct RiotApiConfig {
}
impl RiotApiConfig {
/// Request header name for the Riot API key.
/// Request header name for the Riot API key, `"X-Riot-Token"`.
///
/// When using `set_client_builder`, the supplied builder should include
/// this default header with the Riot API key as the value.
const RIOT_KEY_HEADER: &'static str = "X-Riot-Token";
pub const RIOT_KEY_HEADER: &'static str = "X-Riot-Token";
/// `"https://{}.api.riotgames.com"`
///
@ -92,7 +92,7 @@ impl RiotApiConfig {
/// Creates a new `RiotApiConfig` with the given client builder.
///
/// The client builder default headers should include a value for
/// `RiotApiConfig::RIOT_KEY_HEADER`, otherwise authentication will fail.
/// [`RiotApiConfig::RIOT_KEY_HEADER`] (`"X-Riot-Token"`), otherwise authentication will fail.
///
/// * `retries = 3` (`RiotApiConfig::DEFAULT_RETRIES`).
/// * `burst_factor = 0.99` (`preconfig_burst`).
@ -292,3 +292,9 @@ impl RiotApiConfig {
self
}
}
impl<T: AsRef<[u8]>> From<T> for RiotApiConfig {
fn from(api_key: T) -> Self {
Self::with_key(api_key)
}
}

View file

@ -25,13 +25,13 @@
//! Data structs and endpoints are automatically generated from the
//! [Riot API Reference](https://developer.riotgames.com/api-methods/) ([Swagger](http://www.mingweisamuel.com/riotapi-schema/tool/)).
//!
//! ## Design
//! # Design
//!
//! * Fast, asynchronous, thread-safe.
//! * Automatically retries failed requests.
//! * Supports all endpoints, kept up-to-date using [riotapi-schema](https://github.com/MingweiSamuel/riotapi-schema).
//!
//! ## Usage
//! # Usage
//!
//! ```rust
//! use riven::RiotApi;
@ -42,7 +42,7 @@
//! rt.block_on(async {
//! // Create RiotApi instance from key string.
//! let api_key = std::env!("RGAPI_KEY"); // "RGAPI-01234567-89ab-cdef-0123-456789abcdef";
//! let riot_api = RiotApi::with_key(api_key);
//! let riot_api = RiotApi::new(api_key);
//!
//! // Get summoner data.
//! let summoner = riot_api.summoner_v4()
@ -80,9 +80,14 @@
//! 9) Irelia 46465 (5)
//! 10) Vladimir 37176 (5)
//! ```
//! ### Feature Flags
//! The [`RiotApi` struct documentation](https://docs.rs/riven/latest/riven/struct.RiotApi.html)
//! contains additional usage information. The [tests](https://github.com/MingweiSamuel/Riven/tree/v/2.x.x/riven/tests)
//! and [example proxy](https://github.com/MingweiSamuel/Riven/tree/v/2.x.x/example/proxy)
//! provide more example usage.
//!
//! #### Nightly vs Stable
//! ## Feature Flags
//!
//! ### Nightly vs Stable
//!
//! Enable the `nightly` feature to use nightly-only functionality. This enables
//! [nightly optimizations in the `parking_lot` crate](https://github.com/Amanieu/parking_lot#nightly-vs-stable).
@ -91,7 +96,7 @@
//! riven = { version = "...", features = [ "nightly" ] }
//! ```
//!
//! #### rustls
//! ### rustls
//!
//! Riven uses [reqwest](https://github.com/seanmonstar/reqwest) for making requests. By default, reqwest uses the native TLS library.
//! If you prefer using [rustls](https://github.com/ctz/rustls) you can do so by turning off the Riven default features
@ -103,11 +108,11 @@
//!
//! Riven is additionally able to produce [tracing](https://docs.rs/tracing) spans for requests if the `tracing` feature is enabled. This feature is disabled by default.
//!
//! ### Docs
//! ## Docs
//!
//! [On docs.rs](https://docs.rs/riven/).
//!
//! ### Error Handling
//! ## Error Handling
//!
//! Riven returns either `Result<T>` or `Result<Option<T>>` within futures.
//!
@ -126,12 +131,12 @@
//! attempted, and the Reqwest `Response` object.
//!
//! You can configure the number of time Riven retries using
//! `RiotApiConfig::set_retries(...)` and the `RiotApi::with_config(config)`
//! `RiotApiConfig::set_retries(...)` and the `RiotApi::from_config(config)`
//! constructor. By default, Riven retries up to 3 times (4 requests total).
//! Some errors, such as 400 client errors, are not retried as they would
//! inevitably fail again.
//!
//! ### Semantic Versioning
//! ## Semantic Versioning
//!
//! This package follows semantic versioning to an extent. However, the Riot API
//! itself changes often and does not follow semantic versioning, which makes
@ -147,23 +152,24 @@
//! Parts of Riven that do not depend on Riot API changes do follow semantic
//! versioning.
//!
//! ### Additional Help
//! ## Additional Help
//!
//! Feel free to [make an issue](https://github.com/MingweiSamuel/Riven/issues/new)
//! if you are have any questions or trouble with Riven.
//!
//! ## Development
//! # Development
//!
//! NodeJS is used to generate code for Riven. The
//! [`srcgen/`](https://github.com/MingweiSamuel/Riven/tree/master/srcgen)
//! [`riven/srcgen`](https://github.com/MingweiSamuel/Riven/tree/v/2.x.x/riven/srcgen)
//! folder contains the code and [doT.js](https://olado.github.io/doT/index.html)
//! templates. `index.js` lists the JSON files downloaded and used to generate the
//! code.
//!
//! To set up the srcgen, you will first need to install NodeJS. Then enter the
//! srcgen folder and run `npm ci` (or `npm install`) to install dependencies.
//! `riven/srcgen` folder and run `npm ci` (or `npm install`) to install
//! dependencies.
//!
//! To run the srcgen use `node srcgen` from the main folder.
//! To run the srcgen use `node riven/srcgen` from the repository root.
//!
//!

View file

@ -19,11 +19,16 @@ use crate::util::InsertOnlyCHashMap;
///
/// # Usage
///
/// Construct an instance using [`with_key(api_key)`](RiotApi::with_key) or
/// [`with_config(config)`](RiotApi::with_config).
/// Construct an instance using [`RiotApi::new(api_key or config)`](RiotApi::new).
/// The parameter may be a Riot API key string or a [`RiotApiConfig`]. Riot API
/// keys are obtained from the [Riot Developer Portal](https://developer.riotgames.com/)
/// and look like `"RGAPI-01234567-89ab-cdef-0123-456789abcdef"`.
///
/// An instance provides access to "endpoint handles" which in turn provide access
/// to individual API method calls. For example, getting a summoner by name:
/// An instance provides access to "endpoint handles" which in turn provide
/// access to individual API method calls. For example, to get a summoner by
/// name we first access the [`summoner_v4()`](RiotApi::summoner_v4) endpoints
/// then call the [`get_by_summoner_name()`](crate::endpoints::SummonerV4::get_by_summoner_name)
/// method:
/// ```ignore
/// riot_api.summoner_v4().get_by_summoner_name(Region::NA, "LugnutsK")
/// ```
@ -31,14 +36,14 @@ use crate::util::InsertOnlyCHashMap;
/// # Rate Limiting
///
/// The Riot Game API enforces _dynamic_ rate limiting, meaning that rate limits are
/// specified in response headers and (theoretically) could change at any time.
/// specified in response headers and can change at any time.
/// Riven keeps track of changing rate limits seamlessly, preventing you from
/// getting blacklisted.
///
/// Riven's rate limiting is highly efficient, meaning that it can reach the limits
/// of your rate limit without going over.
/// Riven's rate limiting is highly efficient; it can use the full throughput
/// of your rate limit without triggering 429 errors.
///
/// To adjust rate limiting, see [RiotApiConfig](crate::RiotApiConfig) and use
/// To adjust rate limiting, see [RiotApiConfig] and use
/// [`with_config(config)`](RiotApi::with_config) to construct an instance.
pub struct RiotApi {
/// Configuration settings.
@ -51,10 +56,11 @@ pub struct RiotApi {
}
impl RiotApi {
/// Constructs a new instance from the given [RiotApiConfig](crate::RiotApiConfig), consuming it.
pub fn with_config(mut config: RiotApiConfig) -> Self {
/// Constructs a new instance from an API key (e.g. `"RGAPI-01234567-89ab-cdef-0123-456789abcdef"`) or a [RiotApiConfig].
pub fn new(config: impl Into<RiotApiConfig>) -> Self {
let mut config = config.into();
let client_builder = config.client_builder.take()
.expect("!NONE CLIENT_BUILDER IN CONFIG.");
.expect("CLIENT_BUILDER IN CONFIG SHOULD NOT BE NONE.");
Self {
config: config,
client: client_builder.build().expect("Failed to create client from builder."),
@ -62,13 +68,20 @@ impl RiotApi {
}
}
/// Constructs a new instance from the given [RiotApiConfig](crate::RiotApiConfig), consuming it.
#[deprecated(since = "2.0", note = "use `RiotApi::new(config)` instead")]
pub fn with_config(config: RiotApiConfig) -> Self {
Self::new(config)
}
/// Constructs a new instance from the given API key, using default configuration.
///
/// `api_key` should be a Riot Games API key from
/// [https://developer.riotgames.com/](https://developer.riotgames.com/),
/// and should look like `"RGAPI-01234567-89ab-cdef-0123-456789abcdef"`.
#[deprecated(since = "2.0", note = "use `RiotApi::new(api_key)` instead")]
pub fn with_key(api_key: impl AsRef<[u8]>) -> Self {
Self::with_config(RiotApiConfig::with_key(api_key))
Self::new(api_key)
}
/// This method should generally not be used directly. Consider using endpoint wrappers instead.

View file

@ -9,8 +9,7 @@ lazy_static! {
let api_key = std::env::var("RGAPI_KEY").ok()
.or_else(|| std::fs::read_to_string("apikey.txt").ok())
.expect("Failed to find RGAPI_KEY env var or apikey.txt.");
RiotApi::with_config(RiotApiConfig::with_key(api_key.trim())
.preconfig_burst())
RiotApi::new(RiotApiConfig::with_key(api_key.trim()).preconfig_burst())
};
}