Skip to content

Clarify the use of HTTP GET and POST request #205

Open

Description

@TomokiMiyauci

from GraphQL over HTTP Spec

A server MUST accept POST requests, and MAY accept other HTTP methods, such as GET.

For semantics and performance (caching, etc.), it seems to me that it is recommended to use GET for the query operation.

If the options are not equivalent, it is necessary to clarify which is more appropriate.

Activity

  1. added this to the 1.0 Release milestone on Jul 19, 2022
  2. spawnia commented on Jul 19, 2022

    @spawnia
    Member

    One possible concern I could see with GET requests is the limited length of a URL. Some web server defaults:

    When fragments, unstripped comments, lots of variables and multiple levels of nesting are involved, payloads can get quite large. A quick look at our application logs showed a few queries above 1000 characters.

  3. TomokiMiyauci commented on Jul 20, 2022

    @TomokiMiyauci
    Author

    @spawnia

    RFC 7230

    It is recommended that all HTTP senders and recipients support, at a minimum, It is recommended that all HTTP senders and recipients support, at a minimum, request-line lengths of 8000 octets.

    That is certainly true.

    What do you think about caching of query operation?
    Caching using the POST method seems to be possible, but I am not familiar with it.

    Some implementations have complex mechanisms for handling cache on the client side, but I doubt it is really necessary.

    It would be helpful to have a description of caching in the Spec.

  4. bclozel commented on Dec 15, 2025

    @bclozel

    While it won't solve the problem of "query vs. mutation" operations, using HTTP QUERY would at least solve the limitation of length of URLs.

  5. reschke commented on Jul 9, 2026

    @reschke

    There we go.

    • Yes, QUERY (RFC 10008) solves that. What is a problem though is that there doesn't seem to be a media type that would identify GraphQL is requests.
    • GET is truly REQUIRED (and so is HEAD). Of course the server is free to send a response saying "hey, this is just GQL endpoint)
  6. martinbonnin commented on Jul 13, 2026

    @martinbonnin
    Contributor

    GET is truly REQUIRED (and so is HEAD). Of course the server is free to send a response saying "hey, this is just GQL endpoint)

    @reschke can you ellaborate on that? What's wrong with a server that returns 405 Method Not Allowed for both GET and HEAD?

  7. martinbonnin commented on Aug 11, 2026

    @martinbonnin
    Contributor

    The current QUERY PR recommends using QUERY for queries and POST for mutations.

    I'm not 100% clear how much we need to support GET, HEAD or OPTIONS yet. Accept-Query sounds like it needs one of those. Anything else?

  8. reschke commented on Aug 11, 2026

    @reschke

    GET and HEAD aren't optional in HTTP anyway.

  9. martinbonnin commented on Aug 12, 2026

    @martinbonnin
    Contributor

    Notes for my future self:

    https://www.rfc-editor.org/rfc/rfc9110.html#section-9.1-9

    All general-purpose servers MUST support the methods GET and HEAD. All other methods are OPTIONAL.
    

    My understanding is that this is useful for people (or bots) entering the endpoint URL in their browsers (so that they can have some useful information), and/or infrastructure that may use GET/HEAD as health checks.

    Multiple possibilities to handle GET requests:

    1. replying a GraphQL response if the query query parameter is set (and a request error if it is not) (legacy mode).
    2. replying 405 with Allow: QUERY, POST. (not 100% sure this is allowed but it looks like it is).
    3. replying 200 with a graphiql instance (probably my preferred solution but not everyone will want that).
    4. replying 200 with hey I'm just a GraphQL endpoint.
  10. reschke commented on Aug 12, 2026

    @reschke

    405 for GET is not allowed, as per the spec.

    Just return some useful information about the endpoint (HTML, JSON...).

  11. Shane32 commented on Aug 18, 2026

    @Shane32
    Contributor

    405 for GET is not allowed, as per the spec.

    Just return some useful information about the endpoint (HTML, JSON...).

    RFC 9110 section 9.1 says the HTTP servers need to "support" GET/HEAD; not that they return 200 or any specific status code, or return relevant data.

    All general-purpose servers MUST support the methods GET and HEAD. All other methods are OPTIONAL

    Further, the very next paragraph explains that "recognized and implemented" (i.e. "supported") methods of the server do not need to be allowed for every url:

    An origin server that receives a request method that is recognized and implemented, but not allowed for the target resource, SHOULD respond with the 405 (Method Not Allowed) status code.

    Defining what methods are supported by the server itself is well outside the scope of this protocol. The GraphQL over HTTP protocol is merely defining which method(s) for the configured url is handled by this spec. While perhaps self-evident, maybe it could be clarified.

  12. Shane32 commented on Aug 18, 2026

    @Shane32
    Contributor

    In other words, I think of "server" as used by RFC 9110 is talking about Apache/IIS/etc - a "general-purpose [http] server", whereas "server" when used within the GraphQL-over-HTTP document is typically talking about the specific handler that runs within the context of a RFC 9110 compliant server (Apache/IIS/etc) to handle requests and return responses for specific url/method combinations. We are not defining any general HTTP server behavior addressed by RFC 9110, such as protocol-version handling, field processing, URI processing, error handling, intermediary behavior, and protocol extensibility - and so whether GET/HEAD are "supported" by the underlying HTTP server is out of scope here.

  13. martinbonnin commented on Aug 18, 2026

    @martinbonnin
    Contributor

    405 for GET is not allowed, as per the spec.
    Just return some useful information about the endpoint (HTML, JSON...).

    RFC 9110 section 9.1 says the HTTP servers need to "support" GET/HEAD; not that they return 200 or any specific status code, or return relevant data.

    This was also my immediate understanding. I'm a bit unclear what "support" mean in that context. I'm fine saying returning 405 is not properly supporting GET and I removed it from the options in this comment.

    While perhaps self-evident, maybe it could be clarified.
    whether GET/HEAD are "supported" by the underlying HTTP server is out of scope here.

    Worth being clarified IMO. Even if out of scope, providing some non-normative guidance what to reply to GET would be welcome.

  14. reschke commented on Aug 19, 2026

    @reschke

    Irony alert:

    405 for GET is not allowed, as per the spec.

    Just return some useful information about the endpoint (HTML, JSON...).

    RFC 9110 section 9.1 says the HTTP servers need to "support" GET/HEAD; not that they return 200 or any specific status code, or return
    relevant data.

    https://greenbytes.de/tech/webdav/rfc9110.html#status.405 :

    The 405 (Method Not Allowed) status code indicates that the method received in the request-line is known by the origin server but not supported by the target resource. The origin server MUST generate an Allow header field in a 405 response containing a list of the target resource's currently supported methods.

  15. rstoyanchev commented on Aug 20, 2026

    @rstoyanchev

    Is it correct to think that GET is required because a resource must exist in the first place? A GraphQL endpoint is just a transport, i.e. does not represent a resource, which may be why it doesn't fit well the requirement. One consequence is that a 200 with "hey, this is just GQL endpoint" is not as machine friendly, but maybe if the response and text are defined in the spec, it becomes easier to handle definitively.

    GraphQL seems more aligned with HTTP QUERY, and I'm wondering how does the requirement for GET/HEAD support relate to HTTP QUERY? If a server supports HTTP QUERY at a given URL, what is it expected to return for GET/HEAD?

  16. martinbonnin commented on Aug 20, 2026

    @martinbonnin
    Contributor

    Is it correct to think that GET is required because a resource must exist in the first place? A GraphQL endpoint is just a transport, i.e. does not represent a resource, which may be why it doesn't fit well the requirement.

    I like this way of phrasing the question. Does GraphQL represent a "resource"? I'm not really sure.

    If a server supports HTTP QUERY at a given URL, what is it expected to return for GET/HEAD?

    Some kind of guidance like "Hey, this is a GraphQL endoint. You can send operations to me using QUERY or POST" would probably be helpful for people/agents not super familiar with GraphQL (I know that info would also be in the Allow response header but the newcomers probably won't find it there).

  17. rstoyanchev commented on Aug 20, 2026

    @rstoyanchev

    HTTP QUERY describes an "equivalent resource" where a URL location may be associated with the result which becomes directly accessible via GET. Perhaps not applicable to GraphQL, but treats the question of what is the relationship of HTTP QUERY to a resource and HTTP GET.

  18. Shane32 commented on Aug 23, 2026

    @Shane32
    Contributor

    FYI, these RFCs all specify that 405 may/must be returned for GET requests (vs POST) to a specific resource/endpoint:

    While not documented in an RFC, obviously many REST APIs have resources that do not support GET.

    Seems like we can leave this up to the implementation/developer to support GET if/as desired, such as the options @martinbonnin described. I agree that typically I respond with a GraphiQL instance for my servers, but certainly either returning 405 or supporting GET is common enough.

    Keep in mind also that when persisted documents are in use, the resource (url) might uniquely identify a specific mutation. As such, 405 for GET might be a very appropriate response for those resources - "target resource does not support this method".

  19. benjie commented on Sep 3, 2026

    @benjie
    Member

    Pretty sure an HTTP server MUST support the GET verb, but the given resource MAY return 405 for a GET request, to say that resource doesn't support it. It would be wild if HTTP required that every mutation-only endpoint had to have a GET behavior other than 405 - returning 403 ("Forbidden" to issue GET to this resource) would be fine whether or not 405 is allowed, but 405 is clearly the better match and I can see no good reason why the HTTP spec should forbid it.

    Great examples, @Shane32.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions