Using BatchHttpLink from Apollo in Ariadne

552 views Asked by At

I have my client app written in React + Apollo and backend in Python + Ariadne. Is there any way to handle batched arrays of queries in Ariadne?

I set custom Link in my client:

const apolloClient = new ApolloClient({
   cache: InMemoryCache(),
   link: new BatchHttpLink({ uri })
});

Client started sending queries in the array as expected, but unfortunately I get 400 Bad Request, because backend was expecting an object instead of the array.

I'm not sure if I should create a middleware for Ariadne and handle requests manually or there is some automatic solution? I was trying to Google, but phrases ariadne + batch/batching does not seem to appear together...

2

There are 2 answers

0
Kevin Valk On BEST ANSWER

For future prosperity an easy way to support batch requests would be:

class GraphQLBatchHTTPHandler(GraphQLHTTPHandler):
    async def graphql_http_server(self, request: Request) -> Response:
        try:
            data: Any = await self.extract_data_from_request(request)
        except HttpError as error:
            return PlainTextResponse(error.message or error.status, status_code=400)

        # We check if we are in batch mode
        if isinstance(data, list):
            results: list[Any] = []
            is_error = False
            for d in cast(list[Any], data):
                success, result = await self.execute_graphql_query(request, d)  # type: ignore
                is_error |= not success
                results.append(result)

            return JSONResponse(results, status_code=400 if is_error else 200)

        # We default to normal behavior
        success, result = await self.execute_graphql_query(request, data)  # type: ignore
        return await self.create_json_response(request, result, success)  # type: ignore

And then passing it into Ariadne using

GraphQL(..., http_handler=GraphQLBatchHTTPHandler(), ...)
0
Phil Plückthun On

I haven't really worked with this particular GraphQL server implementation but it's worth noting that the "batched link" indeed simply sends an array of queries, which is a spec extension and not part of the original spec, so if your server-implementation and GraphQL endpoint don't support this you'll have to manually add this.

This isn't a particularly special piece of logic though. It executes all the queries from the array as if they were sent separately. You can find a strawman spec document for this behaviour here: https://github.com/graphql/graphql-over-http/blob/main/rfcs/Batching.md