Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

APQ seems to be partially implemented in Spring Server #2065

Closed
Labels
type: bugSomething isn't working
@malaquf

Description

@malaquf

Library Version
8.2.1

Describe the bug
We tried to enable APQ in spring server, which according to the documentation requires only settingautomaticPersistedQueries.enabled: true, but unfortunately the APQ flow doesn't work as expected because the initial GET call fail in GraphQLServer with bad request without a body (I'd expect a PersistedQueryNotFound error be available in the payload, for eg). The AutomaticPersistedQueriesProvider is not even executed.

The request fails because the parseRequest returns null (no query parameter available):

open suspend fun execute(        request: Request    ): GraphQLServerResponse? =        coroutineScope {            requestParser.parseRequest(request)?.let { graphQLRequest ->                val graphQLContext = contextFactory.generateContext(request)                val customCoroutineContext = (graphQLContext.get<CoroutineContext>() ?: EmptyCoroutineContext)                val graphQLExecutionScope = CoroutineScope(                    coroutineContext + customCoroutineContext + SupervisorJob()                )                val graphQLContextWithCoroutineScope = graphQLContext + mapOf(                    CoroutineScope::class to graphQLExecutionScope                )                requestHandler.executeRequest(graphQLRequest, graphQLContextWithCoroutineScope)            }        }

and therefore the router returns bad request here (GraphQLRoutesConfiguration):

@Bean    fun graphQLRoutes() = coRouter {        val isEndpointRequest = POST(config.endpoint) or GET(config.endpoint)        val isNotWebSocketRequest = headers { isWebSocketHeaders(it) }.not()        (isEndpointRequest and isNotWebSocketRequest).invoke { serverRequest ->            try {                val graphQLResponse = graphQLServer.execute(serverRequest)                val acceptMediaType = serverRequest                    .headers()                    .accept()                    .find { it != MediaType.ALL && it.includes(MediaType.APPLICATION_GRAPHQL_RESPONSE) }                    ?.let { MediaType.APPLICATION_GRAPHQL_RESPONSE }                    ?: MediaType.APPLICATION_JSON                if (graphQLResponse != null) {                    ok().contentType(acceptMediaType).bodyValueAndAwait(graphQLResponse)                } else {                    badRequest().buildAndAwait()                }            } catch (e: Exception) {                badRequest().buildAndAwait()            }        }    }

To Reproduce

We first tried it with Apollo Client and our own requests and saw the router not being able to resolve the request with 400s, and then we tried to reproduce it with simple examples from Apollo as described below:

1st GET request without query returns 400:

curl --get http://localhost:4000/graphql \  --header 'content-type: application/json' \  --data-urlencode 'extensions={"persistedQuery":{"version":1,"sha256Hash":"ecf4edb46db40b5132295c0291d62fb65d6759a9eedfa4d5d612dd5ec54a6b38"}}'

2nd GET request with query returns 200:

  curl --get http://localhost:4000/graphql \  --header 'content-type: application/json' \  --data-urlencode 'query={__typename}' \  --data-urlencode 'extensions={"persistedQuery":{"version":1,"sha256Hash":"ecf4edb46db40b5132295c0291d62fb65d6759a9eedfa4d5d612dd5ec54a6b38"}}'

Send another GET request without the query and the cache is still not checked and we still receive 400:

curl --get http://localhost:4000/graphql \  --header 'content-type: application/json' \  --data-urlencode 'extensions={"persistedQuery":{"version":1,"sha256Hash":"ecf4edb46db40b5132295c0291d62fb65d6759a9eedfa4d5d612dd5ec54a6b38"}}'

Expected behavior
The first call should not fail with bad request, and it should be able to resolve from cache after the result is properly cached.

Also, from the client implementation that's how it's supposed work (first request without a "query" parameter):

val apqRawResultWithoutQuery:String=when (automaticPersistedQueriesSettings.httpMethod) {

Metadata

Metadata

Assignees

No one assigned

    Labels

    type: bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions


      [8]ページ先頭

      ©2009-2025 Movatter.jp