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