TLA Line data Source code
1 : use anyhow::Context;
2 : use bytes::Buf;
3 : use hyper::{header, Body, Request, Response, StatusCode};
4 : use serde::{Deserialize, Serialize};
5 :
6 : use super::error::ApiError;
7 :
8 CBC 3532 : pub async fn json_request<T: for<'de> Deserialize<'de>>(
9 3532 : request: &mut Request<Body>,
10 3532 : ) -> Result<T, ApiError> {
11 3532 : json_request_or_empty_body(request)
12 87 : .await?
13 3532 : .context("missing request body")
14 3532 : .map_err(ApiError::BadRequest)
15 3532 : }
16 :
17 : /// Will be removed as part of <https://github.com/neondatabase/neon/issues/4282>
18 3584 : pub async fn json_request_or_empty_body<T: for<'de> Deserialize<'de>>(
19 3584 : request: &mut Request<Body>,
20 3584 : ) -> Result<Option<T>, ApiError> {
21 3584 : let body = hyper::body::aggregate(request.body_mut())
22 88 : .await
23 3584 : .context("Failed to read request body")
24 3584 : .map_err(ApiError::BadRequest)?;
25 3584 : if body.remaining() == 0 {
26 UBC 0 : return Ok(None);
27 CBC 3584 : }
28 3584 :
29 3584 : let mut deser = serde_json::de::Deserializer::from_reader(body.reader());
30 3584 :
31 3584 : serde_path_to_error::deserialize(&mut deser)
32 3584 : // intentionally stringify because the debug version is not helpful in python logs
33 3584 : .map_err(|e| anyhow::anyhow!("Failed to parse json request: {e}"))
34 3584 : .map(Some)
35 3584 : .map_err(ApiError::BadRequest)
36 3584 : }
37 :
38 11657 : pub fn json_response<T: Serialize>(
39 11657 : status: StatusCode,
40 11657 : data: T,
41 11657 : ) -> Result<Response<Body>, ApiError> {
42 11657 : let json = serde_json::to_string(&data)
43 11657 : .context("Failed to serialize JSON response")
44 11657 : .map_err(ApiError::InternalServerError)?;
45 11657 : let response = Response::builder()
46 11657 : .status(status)
47 11657 : .header(header::CONTENT_TYPE, "application/json")
48 11657 : .body(Body::from(json))
49 11657 : .map_err(|e| ApiError::InternalServerError(e.into()))?;
50 11657 : Ok(response)
51 11657 : }
|