Skip to content

Commit 4e2c8fc

Browse files
feat(room-api): Add GET /rooms-v2 endpoint returning rooms in geojson format
Adds a new rooms-v2 endpoint for returning changing rooms in geojson format. Should make it more intuitive to map the changing rooms using Streamlit/Pydeck. Kind of related to #14
1 parent 1d2c097 commit 4e2c8fc

File tree

3 files changed

+78
-7
lines changed

3 files changed

+78
-7
lines changed

room-api/src/get_rooms.rs

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@ use std::sync::LazyLock;
22

33
use axum::{
44
extract::{Path, State},
5-
http::StatusCode,
5+
http::{header, StatusCode},
6+
response::IntoResponse,
67
Json,
78
};
89
use futures::TryStreamExt;
10+
use geojson::{feature::Id, Feature, FeatureCollection, JsonObject};
911
use mongodb::{
1012
bson::{doc, Uuid},
1113
Database,
1214
};
15+
use serde_json::Value;
1316

1417
use crate::models::ChangingRoom;
1518

@@ -42,6 +45,73 @@ pub async fn get_all_rooms(
4245
Ok(Json(rooms))
4346
}
4447

48+
pub async fn get_all_rooms_v2(
49+
State(db): State<Database>,
50+
) -> Result<impl IntoResponse, (StatusCode, String)> {
51+
let collection = db.collection::<ChangingRoom>("rooms");
52+
53+
let rooms: Vec<ChangingRoom> = collection
54+
.find(doc! {})
55+
.await
56+
.map_err(|e| {
57+
tracing::error!(err = e.to_string(), "Unable to get cursor for all rooms");
58+
GENERIC_DB_ERROR.clone()
59+
})?
60+
.try_collect()
61+
.await
62+
.map_err(|e| {
63+
tracing::error!(err = e.to_string(), "Unable to collect rooms into Vec");
64+
GENERIC_DB_ERROR.clone()
65+
})?;
66+
67+
let rooms_geo = rooms
68+
.into_iter()
69+
.filter_map(|r| {
70+
// ^ Replace with ord map when data migr complete
71+
72+
// Properties
73+
let mut props = JsonObject::new();
74+
props.insert(String::from("name"), Value::String(r.name));
75+
props.insert(
76+
String::from("ratings"),
77+
serde_json::to_value(r.ratings)
78+
.inspect_err(|e| {
79+
tracing::error!(
80+
err = e.to_string(),
81+
room_id = r.id.to_string(),
82+
"Unable to serialize rating"
83+
);
84+
})
85+
.unwrap(),
86+
);
87+
if let Some(ext_id) = r.external_id {
88+
props.insert(String::from("externalId"), Value::String(ext_id));
89+
} else {
90+
props.insert(String::from("externalId"), Value::Null);
91+
}
92+
93+
// Geo Feature
94+
r.location_geo.map(|geo| Feature {
95+
bbox: None,
96+
geometry: Some(geo),
97+
id: Some(Id::String(r.id.to_string())),
98+
properties: Some(props),
99+
foreign_members: None,
100+
})
101+
})
102+
.collect::<Vec<_>>();
103+
104+
Ok((
105+
StatusCode::OK,
106+
[(header::CONTENT_TYPE, "application/geo+json")],
107+
Json(FeatureCollection {
108+
bbox: None,
109+
features: rooms_geo,
110+
foreign_members: None,
111+
}),
112+
))
113+
}
114+
45115
pub async fn get_room_by_id(
46116
Path(id): Path<String>,
47117
State(db): State<Database>,
@@ -64,7 +134,7 @@ pub async fn get_room_by_id(
64134
Some(room) => Ok(Json(room)),
65135
None => Err((
66136
StatusCode::NOT_FOUND,
67-
format!("No room found with id {:?}", id),
137+
format!("No room found with id {id:?}"),
68138
)),
69139
}
70140
}

room-api/src/main.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use tower_http::cors::CorsLayer;
1010

1111
use crate::create_room::create_room;
1212
use crate::delete_room::delete_room;
13-
use crate::get_rooms::{get_all_rooms, get_room_by_id};
13+
use crate::get_rooms::{get_all_rooms, get_all_rooms_v2, get_room_by_id};
1414
use crate::healthcheck::{live, ready};
1515
use crate::update_room::update_room;
1616

@@ -32,6 +32,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
3232
.route("/livez", routing::get(live))
3333
.route("/rooms", routing::post(create_room))
3434
.route("/rooms", routing::get(get_all_rooms))
35+
.route("/rooms-v2", routing::get(get_all_rooms_v2))
3536
.route("/rooms/:id", routing::get(get_room_by_id))
3637
.route("/rooms/:id", routing::put(update_room))
3738
.route("/rooms/:id", routing::delete(delete_room))

room-api/src/models.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ pub struct Location {
2323

2424
#[derive(Clone, Debug, Serialize, Deserialize)]
2525
pub struct Ratings {
26-
availability: StarRating,
27-
safety: StarRating,
28-
cleanliness: StarRating,
26+
pub availability: StarRating,
27+
pub safety: StarRating,
28+
pub cleanliness: StarRating,
2929
}
3030

31-
type StarRating = BoundedU8<1, 5>;
31+
pub type StarRating = BoundedU8<1, 5>;

0 commit comments

Comments
 (0)