Skip to content

Commit 52b33b6

Browse files
committed
Add a "minimal crate metadata" API endpoint
As mentioned in #4503 and renovatebot/renovate#3486, this is intended to be a lighter-weight API than /crates/:crate_id, which can be subject to looser rate limits.
1 parent 414d61f commit 52b33b6

File tree

5 files changed

+32
-11
lines changed

5 files changed

+32
-11
lines changed

src/controllers/krate/metadata.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ pub fn summary(req: &mut dyn RequestExt) -> EndpointResult {
4545
.map(|((top_versions, krate), recent_downloads)| {
4646
Ok(EncodableCrate::from_minimal(
4747
krate,
48-
&top_versions,
48+
Some(&top_versions),
4949
None,
5050
false,
5151
recent_downloads,
@@ -159,7 +159,7 @@ pub fn show(req: &mut dyn RequestExt) -> EndpointResult {
159159
Ok(req.json(&json!({
160160
"crate": EncodableCrate::from(
161161
krate.clone(),
162-
&top_versions,
162+
Some(&top_versions),
163163
Some(ids),
164164
Some(&kws),
165165
Some(&cats),
@@ -176,6 +176,26 @@ pub fn show(req: &mut dyn RequestExt) -> EndpointResult {
176176
})))
177177
}
178178

179+
/// Handles the `GET /crates/:crate_id/crate` route.
180+
///
181+
/// A minimal version of [`show`] that only covers the crate itself, without versions or catalog information
182+
/// (such as keywords and categories).
183+
pub fn krate(req: &mut dyn RequestExt) -> EndpointResult {
184+
let name = &req.params()["crate_id"];
185+
let conn = req.db_read_only()?;
186+
let krate: Crate = Crate::by_name(name).first(&*conn)?;
187+
188+
Ok(req.json(&json!({
189+
"crate": EncodableCrate::from_minimal(
190+
krate,
191+
None,
192+
None,
193+
false,
194+
None,
195+
),
196+
})))
197+
}
198+
179199
/// Handles the `GET /crates/:crate_id/:version/readme` route.
180200
pub fn readme(req: &mut dyn RequestExt) -> EndpointResult {
181201
let crate_name = &req.params()["crate_id"];

src/controllers/krate/publish.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ pub fn publish(req: &mut dyn RequestExt) -> EndpointResult {
252252
};
253253

254254
Ok(req.json(&GoodCrate {
255-
krate: EncodableCrate::from_minimal(krate, &top_versions, None, false, None),
255+
krate: EncodableCrate::from_minimal(krate, Some(&top_versions), None, false, None),
256256
warnings,
257257
}))
258258
})

src/controllers/krate/search.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ pub fn search(req: &mut dyn RequestExt) -> EndpointResult {
330330
|((((max_version, krate), perfect_match), recent_downloads), badges)| {
331331
EncodableCrate::from_minimal(
332332
krate,
333-
&max_version,
333+
Some(&max_version),
334334
Some(badges),
335335
perfect_match,
336336
Some(recent_downloads),

src/router.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ pub fn build_router(app: &App) -> RouteBuilder {
3636

3737
// Routes used by the frontend
3838
api_router.get("/crates/:crate_id", C(krate::metadata::show));
39+
api_router.get("/crates/:crate_id/crate", C(krate::metadata::krate));
3940
api_router.get("/crates/:crate_id/:version", C(version::metadata::show));
4041
api_router.get(
4142
"/crates/:crate_id/:version/readme",

src/views.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ impl EncodableCrate {
238238
#[allow(clippy::too_many_arguments)]
239239
pub fn from(
240240
krate: Crate,
241-
top_versions: &TopVersions,
241+
top_versions: Option<&TopVersions>,
242242
versions: Option<Vec<i32>>,
243243
keywords: Option<&[Keyword]>,
244244
categories: Option<&[Category]>,
@@ -267,18 +267,18 @@ impl EncodableCrate {
267267
let documentation = Self::remove_blocked_documentation_urls(documentation);
268268

269269
let max_version = top_versions
270-
.highest
271-
.as_ref()
270+
.and_then(|v| v.highest.as_ref())
272271
.map(|v| v.to_string())
273272
.unwrap_or_else(|| "0.0.0".to_string());
274273

275274
let newest_version = top_versions
276-
.newest
277-
.as_ref()
275+
.and_then(|v| v.newest.as_ref())
278276
.map(|v| v.to_string())
279277
.unwrap_or_else(|| "0.0.0".to_string());
280278

281-
let max_stable_version = top_versions.highest_stable.as_ref().map(|v| v.to_string());
279+
let max_stable_version = top_versions
280+
.and_then(|v| v.highest_stable.as_ref())
281+
.map(|v| v.to_string());
282282

283283
EncodableCrate {
284284
id: name.clone(),
@@ -312,7 +312,7 @@ impl EncodableCrate {
312312

313313
pub fn from_minimal(
314314
krate: Crate,
315-
top_versions: &TopVersions,
315+
top_versions: Option<&TopVersions>,
316316
badges: Option<Vec<Badge>>,
317317
exact_match: bool,
318318
recent_downloads: Option<i64>,

0 commit comments

Comments
 (0)