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