This commit is contained in:
Elijah McMorris 2023-11-23 23:45:49 +00:00
parent 4e3dedf7ab
commit 85294d5983
5 changed files with 31 additions and 10 deletions

View file

@ -24,3 +24,4 @@ strum_macros = "0.25"
tower = { version = "0.4", features = ["limit", "buffer"] }
tower-http = { version = "0.4", features = ["compression-zstd", "cors"] }
tower_governor = "0.1"
lazy_static = "1.4"

View file

@ -18,6 +18,8 @@ Create data folder next to docker-compose.yml, `data\parquet\*.parquet` with the
`docker compose up --pull always`
If not using nginx, set environment NGINX = false in docker compose
# Dev Install
## Dev Containers
Install docker, vscode and the [Dev Containers Extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)

View file

@ -8,6 +8,8 @@ services:
DOCKER_BUILDKIT: 1
container_name: ark-invest-api-rust
restart: unless-stopped
# environment:
# - NGINX = false
volumes:
- ./data:/ark-invest-api-rust/data
ports:

View file

@ -4,6 +4,8 @@ services:
image: ghcr.io/nexveridian/ark-invest-api-rust:latest
container_name: ark-invest-api-rust
restart: unless-stopped
# environment:
# - NGINX = false
volumes:
- ./data:/ark-invest-api-rust/data
ports:

View file

@ -12,7 +12,8 @@ use axum::{
http::{Method, StatusCode},
BoxError, Extension, Json,
};
use std::{net::SocketAddr, time::Duration};
use lazy_static::lazy_static;
use std::{env, net::SocketAddr, time::Duration};
use tower::{buffer::BufferLayer, limit::RateLimitLayer, ServiceBuilder};
use tower_governor::{
governor::GovernorConfigBuilder, key_extractor::SmartIpKeyExtractor, GovernorLayer,
@ -24,6 +25,16 @@ use tower_http::{
mod routes;
lazy_static! {
static ref NGINX: bool = match env::var("NGINX") {
Ok(val) => val
.to_lowercase()
.parse::<bool>()
.expect("Env string NGINX must be bool"),
Err(_) => true,
};
}
async fn serve_api(Extension(api): Extension<OpenApi>) -> impl IntoApiResponse {
Json(api)
}
@ -58,8 +69,8 @@ async fn main() {
let rate_limit_ip = || {
let config = Box::new(
GovernorConfigBuilder::default()
.per_second(2)
.burst_size(10)
.per_millisecond(500)
.burst_size(25)
.use_headers()
.key_extractor(SmartIpKeyExtractor)
.finish()
@ -81,6 +92,13 @@ async fn main() {
)
};
let route_layer = {
rate_limit_global(1_000)
.layer(cors())
.layer(CompressionLayer::new().zstd(true))
.option_layer(if *NGINX { Some(rate_limit_ip()) } else { None })
};
let app = ApiRouter::new()
.route("/", Redoc::new("/api.json").axum_route())
.layer(CompressionLayer::new().zstd(true))
@ -96,17 +114,12 @@ async fn main() {
| date | str | str | str | i64 | f64 | f64 | f64 |
### Example
`/ark_holdings?ticker=ARKK&start=2023-01-01&end=2023-03-01`",
`/ark_holdings?ticker=ARKK&start=2023-10-01&end=2023-11-01`",
);
description_date(o)
}),
)
.layer(
rate_limit_global(1000)
.layer(rate_limit_ip())
.layer(cors())
.layer(CompressionLayer::new().zstd(true)),
);
.layer(route_layer);
let mut api = OpenApi {
info: Info {
@ -130,6 +143,7 @@ async fn main() {
.serve(
app.finish_api(&mut api)
.layer(Extension(api))
.layer(CompressionLayer::new().zstd(true))
.into_make_service(),
)
.await