Skip to content

Commit

Permalink
axum-extra: Use json!() macro (#9960)
Browse files Browse the repository at this point in the history
This seems a bit easier to use than the `Json(json!(...))` construct and is apparently even a bit faster since it does not need to allocate as much memory.
  • Loading branch information
Turbo87 authored Nov 16, 2024
1 parent fa7b413 commit 64c1aa7
Show file tree
Hide file tree
Showing 36 changed files with 152 additions and 122 deletions.
12 changes: 12 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ aws-ip-ranges = "=0.913.0"
aws-sdk-cloudfront = "=1.52.0"
aws-sdk-sqs = "=1.49.0"
axum = { version = "=0.7.8", features = ["macros", "matched-path"] }
axum-extra = { version = "=0.9.5", features = ["cookie-signed", "typed-header"] }
axum-extra = { version = "=0.9.5", features = ["cookie-signed", "erased-json", "typed-header"] }
base64 = "=0.22.1"
bigdecimal = { version = "=0.4.6", features = ["serde"] }
bon = "=3.0.0"
Expand Down
18 changes: 9 additions & 9 deletions src/controllers/category.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ use crate::util::errors::AppResult;
use crate::util::RequestUtils;
use crate::views::{EncodableCategory, EncodableCategoryWithSubcategories};
use axum::extract::Path;
use axum::Json;
use axum_extra::json;
use axum_extra::response::ErasedJson;
use diesel::QueryDsl;
use diesel_async::RunQueryDsl;
use http::request::Parts;
use serde_json::Value;

/// Handles the `GET /categories` route.
pub async fn index(app: AppState, req: Parts) -> AppResult<Json<Value>> {
pub async fn index(app: AppState, req: Parts) -> AppResult<ErasedJson> {
// FIXME: There are 69 categories, 47 top level. This isn't going to
// grow by an OoM. We need a limit for /summary, but we don't need
// to paginate this.
Expand All @@ -35,14 +35,14 @@ pub async fn index(app: AppState, req: Parts) -> AppResult<Json<Value>> {
// Query for the total count of categories
let total = Category::count_toplevel(&mut conn).await?;

Ok(Json(json!({
Ok(json!({
"categories": categories,
"meta": { "total": total },
})))
}))
}

/// Handles the `GET /categories/:category_id` route.
pub async fn show(state: AppState, Path(slug): Path<String>) -> AppResult<Json<Value>> {
pub async fn show(state: AppState, Path(slug): Path<String>) -> AppResult<ErasedJson> {
let mut conn = state.db_read().await?;

let cat: Category = Category::by_slug(&slug).first(&mut conn).await?;
Expand Down Expand Up @@ -71,11 +71,11 @@ pub async fn show(state: AppState, Path(slug): Path<String>) -> AppResult<Json<V
parent_categories: parents,
};

Ok(Json(json!({ "category": cat_with_subcats })))
Ok(json!({ "category": cat_with_subcats }))
}

/// Handles the `GET /category_slugs` route.
pub async fn slugs(state: AppState) -> AppResult<Json<Value>> {
pub async fn slugs(state: AppState) -> AppResult<ErasedJson> {
let mut conn = state.db_read().await?;

let slugs: Vec<Slug> = categories::table
Expand All @@ -91,5 +91,5 @@ pub async fn slugs(state: AppState) -> AppResult<Json<Value>> {
description: String,
}

Ok(Json(json!({ "category_slugs": slugs })))
Ok(json!({ "category_slugs": slugs }))
}
19 changes: 10 additions & 9 deletions src/controllers/crate_owner_invitation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,19 @@ use crate::views::{
};
use axum::extract::Path;
use axum::Json;
use axum_extra::json;
use axum_extra::response::ErasedJson;
use chrono::{Duration, Utc};
use diesel::pg::Pg;
use diesel::sql_types::Bool;
use diesel_async::async_connection_wrapper::AsyncConnectionWrapper;
use http::request::Parts;
use indexmap::IndexMap;
use serde_json::Value;
use std::collections::{HashMap, HashSet};
use tokio::runtime::Handle;

/// Handles the `GET /api/v1/me/crate_owner_invitations` route.
pub async fn list(app: AppState, req: Parts) -> AppResult<Json<Value>> {
pub async fn list(app: AppState, req: Parts) -> AppResult<ErasedJson> {
let mut conn = app.db_read().await?;
let auth = AuthCheck::only_cookie().check(&req, &mut conn).await?;
spawn_blocking(move || {
Expand Down Expand Up @@ -59,10 +60,10 @@ pub async fn list(app: AppState, req: Parts) -> AppResult<Json<Value>> {
})
.collect::<AppResult<Vec<EncodableCrateOwnerInvitationV1>>>()?;

Ok(Json(json!({
Ok(json!({
"crate_owner_invitations": crate_owner_invitations,
"users": users,
})))
}))
})
.await
}
Expand Down Expand Up @@ -275,7 +276,7 @@ struct OwnerInvitation {
}

/// Handles the `PUT /api/v1/me/crate_owner_invitations/:crate_id` route.
pub async fn handle_invite(state: AppState, req: BytesRequest) -> AppResult<Json<Value>> {
pub async fn handle_invite(state: AppState, req: BytesRequest) -> AppResult<ErasedJson> {
let (parts, body) = req.0.into_parts();

let crate_invite: OwnerInvitation =
Expand All @@ -299,14 +300,14 @@ pub async fn handle_invite(state: AppState, req: BytesRequest) -> AppResult<Json
invitation.decline(&mut conn).await?;
}

Ok(Json(json!({ "crate_owner_invitation": crate_invite })))
Ok(json!({ "crate_owner_invitation": crate_invite }))
}

/// Handles the `PUT /api/v1/me/crate_owner_invitations/accept/:token` route.
pub async fn handle_invite_with_token(
state: AppState,
Path(token): Path<String>,
) -> AppResult<Json<Value>> {
) -> AppResult<ErasedJson> {
let mut conn = state.db_write().await?;
let invitation = CrateOwnerInvitation::find_by_token(&token, &mut conn).await?;

Expand All @@ -315,10 +316,10 @@ pub async fn handle_invite_with_token(
let crate_id = invitation.crate_id;
invitation.accept(&mut conn, config).await?;

Ok(Json(json!({
Ok(json!({
"crate_owner_invitation": {
"crate_id": crate_id,
"accepted": true,
},
})))
}))
}
4 changes: 2 additions & 2 deletions src/controllers/helpers.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use crate::util::errors::AppResult;
use axum::response::{IntoResponse, Response};
use axum::Json;
use axum_extra::json;

pub(crate) mod pagination;

pub(crate) use self::pagination::Paginate;

pub fn ok_true() -> AppResult<Response> {
let json = json!({ "ok": true });
Ok(Json(json).into_response())
Ok(json.into_response())
}
14 changes: 7 additions & 7 deletions src/controllers/keyword.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@ use crate::tasks::spawn_blocking;
use crate::util::errors::AppResult;
use crate::views::EncodableKeyword;
use axum::extract::{Path, Query};
use axum::Json;
use axum_extra::json;
use axum_extra::response::ErasedJson;
use diesel::prelude::*;
use diesel_async::async_connection_wrapper::AsyncConnectionWrapper;
use http::request::Parts;
use serde_json::Value;

#[derive(Deserialize)]
pub struct IndexQuery {
sort: Option<String>,
}

/// Handles the `GET /keywords` route.
pub async fn index(state: AppState, qp: Query<IndexQuery>, req: Parts) -> AppResult<Json<Value>> {
pub async fn index(state: AppState, qp: Query<IndexQuery>, req: Parts) -> AppResult<ErasedJson> {
use crate::schema::keywords;

let mut query = keywords::table.into_boxed();
Expand All @@ -41,18 +41,18 @@ pub async fn index(state: AppState, qp: Query<IndexQuery>, req: Parts) -> AppRes
.map(Keyword::into)
.collect::<Vec<EncodableKeyword>>();

Ok(Json(json!({
Ok(json!({
"keywords": kws,
"meta": { "total": total },
})))
}))
})
.await
}

/// Handles the `GET /keywords/:keyword_id` route.
pub async fn show(Path(name): Path<String>, state: AppState) -> AppResult<Json<Value>> {
pub async fn show(Path(name): Path<String>, state: AppState) -> AppResult<ErasedJson> {
let mut conn = state.db_read().await?;
let kw = Keyword::find_by_keyword(&mut conn, &name).await?;

Ok(Json(json!({ "keyword": EncodableKeyword::from(kw) })))
Ok(json!({ "keyword": EncodableKeyword::from(kw) }))
}
10 changes: 5 additions & 5 deletions src/controllers/krate/downloads.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ use crate::sql::to_char;
use crate::util::errors::{crate_not_found, AppResult};
use crate::views::EncodableVersionDownload;
use axum::extract::Path;
use axum::Json;
use axum_extra::json;
use axum_extra::response::ErasedJson;
use diesel::prelude::*;
use diesel_async::RunQueryDsl;
use serde_json::Value;
use std::cmp;

/// Handles the `GET /crates/:crate_id/downloads` route.
pub async fn downloads(state: AppState, Path(crate_name): Path<String>) -> AppResult<Json<Value>> {
pub async fn downloads(state: AppState, Path(crate_name): Path<String>) -> AppResult<ErasedJson> {
let mut conn = state.db_read().await?;

use diesel::dsl::*;
Expand Down Expand Up @@ -68,10 +68,10 @@ pub async fn downloads(state: AppState, Path(crate_name): Path<String>) -> AppRe
downloads: i64,
}

Ok(Json(json!({
Ok(json!({
"version_downloads": downloads,
"meta": {
"extra_downloads": extra,
},
})))
}))
}
8 changes: 4 additions & 4 deletions src/controllers/krate/follow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ use crate::schema::*;
use crate::util::errors::{crate_not_found, AppResult};
use axum::extract::Path;
use axum::response::Response;
use axum::Json;
use axum_extra::json;
use axum_extra::response::ErasedJson;
use diesel::prelude::*;
use diesel_async::{AsyncPgConnection, RunQueryDsl};
use http::request::Parts;
use serde_json::Value;

async fn follow_target(
crate_name: &str,
Expand Down Expand Up @@ -66,7 +66,7 @@ pub async fn following(
app: AppState,
Path(crate_name): Path<String>,
req: Parts,
) -> AppResult<Json<Value>> {
) -> AppResult<ErasedJson> {
use diesel::dsl::exists;

let mut conn = app.db_read_prefer_primary().await?;
Expand All @@ -80,5 +80,5 @@ pub async fn following(
.get_result::<bool>(&mut conn)
.await?;

Ok(Json(json!({ "following": following })))
Ok(json!({ "following": following }))
}
20 changes: 10 additions & 10 deletions src/controllers/krate/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,20 @@ use crate::views::{
};
use axum::extract::Path;
use axum::response::{IntoResponse, Response};
use axum::Json;
use axum_extra::json;
use axum_extra::response::ErasedJson;
use diesel_async::async_connection_wrapper::AsyncConnectionWrapper;
use http::request::Parts;
use serde_json::Value;
use std::cmp::Reverse;
use std::str::FromStr;

/// Handles the `GET /crates/new` special case.
pub async fn show_new(app: AppState, req: Parts) -> AppResult<Json<Value>> {
pub async fn show_new(app: AppState, req: Parts) -> AppResult<ErasedJson> {
show(app, Path("new".to_string()), req).await
}

/// Handles the `GET /crates/:crate_id` route.
pub async fn show(app: AppState, Path(name): Path<String>, req: Parts) -> AppResult<Json<Value>> {
pub async fn show(app: AppState, Path(name): Path<String>, req: Parts) -> AppResult<ErasedJson> {
let conn = app.db_read().await?;
spawn_blocking(move || {
use diesel::RunQueryDsl;
Expand Down Expand Up @@ -157,12 +157,12 @@ pub async fn show(app: AppState, Path(name): Path<String>, req: Parts) -> AppRes
.map(Category::into)
.collect::<Vec<EncodableCategory>>()
});
Ok(Json(json!({
Ok(json!({
"crate": encodable_crate,
"versions": encodable_versions,
"keywords": encodable_keywords,
"categories": encodable_cats,
})))
}))
})
.await
}
Expand Down Expand Up @@ -237,7 +237,7 @@ pub async fn readme(
) -> Response {
let redirect_url = app.storage.readme_location(&crate_name, &version);
if req.wants_json() {
Json(json!({ "url": redirect_url })).into_response()
json!({ "url": redirect_url }).into_response()
} else {
redirect(redirect_url)
}
Expand All @@ -248,7 +248,7 @@ pub async fn reverse_dependencies(
app: AppState,
Path(name): Path<String>,
req: Parts,
) -> AppResult<Json<Value>> {
) -> AppResult<ErasedJson> {
use diesel_async::RunQueryDsl;

let mut conn = app.db_read().await?;
Expand Down Expand Up @@ -295,9 +295,9 @@ pub async fn reverse_dependencies(
})
.collect::<Vec<_>>();

Ok(Json(json!({
Ok(json!({
"dependencies": rev_deps,
"versions": versions,
"meta": { "total": total },
})))
}))
}
Loading

0 comments on commit 64c1aa7

Please sign in to comment.