async_graphql_poem/
query.rs1use std::time::Duration;
2
3use async_graphql::{
4 Executor,
5 http::{create_multipart_mixed_stream, is_accept_multipart_mixed},
6};
7use futures_util::StreamExt;
8use poem::{Body, Endpoint, FromRequest, IntoResponse, Request, Response, Result};
9
10use crate::{GraphQLBatchRequest, GraphQLBatchResponse, GraphQLRequest};
11
12pub struct GraphQL<E> {
36 executor: E,
37}
38
39impl<E> GraphQL<E> {
40 pub fn new(executor: E) -> Self {
42 Self { executor }
43 }
44}
45
46impl<E> Endpoint for GraphQL<E>
47where
48 E: Executor,
49{
50 type Output = Response;
51
52 async fn call(&self, req: Request) -> Result<Self::Output> {
53 let is_accept_multipart_mixed = req
54 .header("accept")
55 .map(is_accept_multipart_mixed)
56 .unwrap_or_default();
57
58 if is_accept_multipart_mixed {
59 let (req, mut body) = req.split();
60 let req = GraphQLRequest::from_request(&req, &mut body).await?;
61 let stream = self.executor.execute_stream(req.0, None);
62 Ok(Response::builder()
63 .header("content-type", "multipart/mixed; boundary=graphql")
64 .body(Body::from_bytes_stream(
65 create_multipart_mixed_stream(stream, Duration::from_secs(30))
66 .map(Ok::<_, std::io::Error>),
67 )))
68 } else {
69 let (req, mut body) = req.split();
70 let req = GraphQLBatchRequest::from_request(&req, &mut body).await?;
71 Ok(GraphQLBatchResponse(self.executor.execute_batch(req.0).await).into_response())
72 }
73 }
74}