学习教程
通过 HTTP 提供服务

通过 HTTP 提供服务

¥Serving over HTTP

Respond to GraphQL requests using an HTTP server

GraphQL 规范在发送 API 请求和响应时不需要特定的客户端-服务器协议,但由于 HTTP 的普遍性,它是最常见的选择。在此页面上,我们将回顾在设置 GraphQL 服务器以通过 HTTP 运行时要遵循的一些关键准则。

¥The GraphQL specification doesn’t require particular client-server protocols when sending API requests and responses, but HTTP is the most common choice because of its ubiquity. On this page, we’ll review some key guidelines to follow when setting up a GraphQL server to operate over HTTP.

请注意,以下准则仅适用于无状态查询和变异操作。访问 订阅页面 以获取有关通常支持这些请求的传输协议的更多信息。

¥Note that the guidelines that follow only apply to stateless query and mutation operations. Visit the Subscriptions page for more information on transport protocols that commonly support these requests.

本页上的建议与当前正在开发的详细 GraphQL-over-HTTP 规范 一致。虽然尚未最终确定,但该草案规范可作为 GraphQL 客户端和库维护人员的单一真实来源,详细说明如何使用 HTTP 传输来公开和使用 GraphQL API。与语言规范不同,遵守不是强制性的,但大多数实现都在朝着这些标准发展,以最大限度地提高互操作性。

¥The recommendations on this page align with the detailed GraphQL-over-HTTP specification currently in development. Though not yet finalized, this draft specification acts as a single source of truth for GraphQL client and library maintainers, detailing how to expose and consume a GraphQL API using an HTTP transport. Unlike the language specification, adherence is not mandatory, but most implementations are moving towards these standards to maximize interoperability.

API 端点

¥API endpoint

HTTP 通常与 REST 联系在一起,REST 使用 “resources” 作为其核心概念。相比之下,GraphQL 的概念模型是 实体图。因此,GraphQL 中的实体不是通过 URL 来标识的。相反,GraphQL 服务器在单个 URL/端点(通常是 /graphql)上运行,并且给定服务的所有 GraphQL 请求都应定向到此端点。

¥HTTP is commonly associated with REST, which uses “resources” as its core concept. In contrast, GraphQL’s conceptual model is an entity graph. As a result, entities in GraphQL are not identified by URLs. Instead, a GraphQL server operates on a single URL/endpoint, usually /graphql, and all GraphQL requests for a given service should be directed to this endpoint.

身份验证发生的位置

¥Where auth happens

大多数现代 Web 框架都使用管道模型,其中请求通过中间件堆栈传递,中间件也称为过滤器或插件。当请求流经管道时,可以对其进行检查、转换、修改或通过响应终止。GraphQL 应放置在所有身份验证中间件之后,以便你可以访问与其他 HTTP 端点处理程序相同的会话和用户信息。

¥Most modern web frameworks use a pipeline model where requests are passed through a stack of middleware, also known as filters or plugins. As the request flows through the pipeline, it can be inspected, transformed, modified, or terminated with a response. GraphQL should be placed after all authentication middleware so that you have access to the same session and user information you would in your other HTTP endpoint handlers.

身份验证后,服务器不应该对请求做出任何 authorization 决定,直到 GraphQL 执行开始。具体来说,字段级授权应由 GraphQL 的 ExecuteRequest() 期间从解析器调用的业务逻辑执行,以便在出现与授权相关的错误时生成部分响应。

¥After authentication, the server should not make any authorization decisions about the request until GraphQL execution begins. Specifically, field-level authorization should be enforced by the business logic called from resolvers during GraphQL’s ExecuteRequest(), allowing for a partial response to be generated if authorization-related errors are raised.

请求格式

¥Request format

标头

¥Headers

GraphQL 客户端和服务器应该支持 JSON 进行序列化,也可能支持其他格式。客户端还应使用 Accept HTTP 标头在响应中指示它们支持哪些媒体类型。具体来说,客户端应将 application/graphql-response+json 包含在 Accept 标头中。

¥GraphQL clients and servers should support JSON for serialization and may support other formats. Clients should also indicate what media types they support in responses using the Accept HTTP header. Specifically, the client should include the application/graphql-response+json in the Accept header.

如果此标头中不包含任何编码信息,则将假定为 utf-8。但是,如果客户端未在请求中提供 Accept 标头,则服务器可能会响应错误。

¥If no encoding information is included with this header, then it will be assumed to be utf-8. However, the server may respond with an error if a client doesn’t provide the Accept header with a request.

application/graphql-response+json 在 GraphQL over HTTP 规范草案中进行了描述。为了确保兼容性,如果客户端在 2025 年 1 月 1 日之前向旧版 GraphQL 服务器发送请求,则 Accept 标头还应包含 application/json 媒体类型,如下所示:application/graphql-response+json;charset=utf-8, application/json;charset=utf-8

¥The application/graphql-response+json is described in the draft GraphQL over HTTP specification. To ensure compatibility, if a client sends a request to a legacy GraphQL server before 1st January 2025, the Accept header should also include the application/json media type as follows: application/graphql-response+json;charset=utf-8, application/json;charset=utf-8

方法

¥Methods

你的 GraphQL HTTP 服务器必须处理 HTTP POST 方法的查询和变异操作,并且还可以接受 GET 方法的查询操作。

¥Your GraphQL HTTP server must handle the HTTP POST method for query and mutation operations, and may also accept the GET method for query operations.

POST 请求和正文

¥POST request and body

标准 GraphQL POST 请求应为其 Content-type 标头设置 application/json,并包含以下形式的 JSON 编码主体:

¥A standard GraphQL POST request should set application/json for its Content-type header, and include a JSON-encoded body of the following form:

{
  "query": "...",
  "operationName": "...",
  "variables": { "myVariable": "someValue", ... },
  "extensions": { "myExtension": "someValue", ... }
}

query 参数是必需的,将包含 GraphQL 文档的源文本。请注意,此处的术语 query 是一个误称:文档可能包含任何有效的 GraphQL 操作(和相关片段)。

¥The query parameter is required and will contain the source text of a GraphQL document. Note that the term query here is a misnomer: the document may contain any valid GraphQL operations (and associated fragments).

operationNamevariablesextensions 参数是可选字段。仅当 query 文档中存在多个操作时才需要 operationName

¥The operationName, variables, and extensions parameters are optional fields. operationName is only required if multiple operations are present in the query document.

请注意,如果客户端请求中缺少 Content-type 标头,则服务器应使用 4xx 状态代码进行响应。与 Accept 标头一样,当未明确提供此信息时,对于具有 application/json 媒体类型的请求主体,假定为 utf-8 编码。

¥Note that if the Content-type header is missing in the client’s request, then the server should respond with a 4xx status code. As with the Accept header, utf-8 encoding is assumed for a request body with an application/json media type when this information is not explicitly provided.

GET 请求和参数

¥GET request and parameters

接收 HTTP GET 请求时,应在查询字符串的 query 参数中提供 GraphQL 文档。例如,如果我们想执行以下 GraphQL 查询:

¥When receiving an HTTP GET request, the GraphQL document should be provided in the query parameter of the query string. For example, if we wanted to execute the following GraphQL query:

{
  me {
    name
  }
}

该请求可以通过 HTTP GET 发送,如下所示:

¥This request could be sent via an HTTP GET like so:

http://myapi/graphql?query={me{name}}

查询变量可以作为 JSON 编码字符串在名为 variables 的附加查询参数中发送。如果查询包含多个命名操作,则可以使用 operationName 查询参数来控制应执行哪一个。

¥Query variables can be sent as a JSON-encoded string in an additional query parameter called variables. If the query contains several named operations, an operationName query parameter can be used to control which one should be executed.

选择 HTTP 方法

¥Choosing an HTTP method

在为 GraphQL 请求选择 HTTP 方法时,有几点需要考虑。首先,对 POST 以外的 HTTP 方法的支持将由 GraphQL 服务器自行决定,因此客户端将仅限于支持的动词。

¥When choosing an HTTP method for a GraphQL request, there are a few points to consider. First, support for HTTP methods other than POST will be at the discretion of the GraphQL server, so a client will be limited to the supported verbs.

此外,GET HTTP 方法只能用于 query 操作,因此如果客户端请求执行 mutation 操作,则必须改用 POST 方法。

¥Additionally, the GET HTTP method may only be used for query operations, so if a client requests execution of a mutation operation then it must use the POST method instead.

当服务器确实支持 GET 方法进行查询操作时,可能会鼓励客户端利用此选项来促进内容交付网络 (CDN) 中的 HTTP 缓存或边缘缓存。但是,由于 GraphQL 文档字符串对于复杂操作可能很长,因此查询参数可能会超出浏览器和 CDN 对 URL 长度的限制。

¥When servers do support the GET method for query operations, a client may be encouraged to leverage this option to facilitate HTTP caching or edge caching in a content delivery network (CDN). However, because GraphQL documents strings may be quite long for complex operations, the query parameters may exceed the limits that browsers and CDNs impose on URL lengths.

在这些情况下,一种常见的方法是服务器使用 持久化文档、自动持久查询或受信任文档等技术存储已识别的 GraphQL 文档。这允许客户端发送简短的文档标识符而不是完整的查询文本。

¥In these cases, a common approach is for the server to store identified GraphQL documents using a technique such as persisted documents, automatic persisted queries, or trusted documents. This allows the client to send a short document identifier instead of the full query text.

响应格式

¥Response format

标头

¥Headers

响应类型应为 application/graphql-response+json,但可以是 application/json 以支持旧版客户端。服务器将在响应的 Content-type 标头中指示媒体类型。它还应该指示编码,否则将假定为 utf-8

¥The response type should be application/graphql-response+json but can be application/json to support legacy clients. The server will indicate the media type in the Content-type header of the response. It should also indicate the encoding, otherwise utf-8 will be assumed.

正文

¥Body

无论使用哪种 HTTP 方法发送查询和变量,响应都应以 JSON 格式返回请求正文中。如 GraphQL 规范中所述,查询可能会导致一些数据和一些错误,这些应该以以下形式的 JSON 对象返回:

¥Regardless of the HTTP method used to send the query and variables, the response should be returned in the body of the request in JSON format. As mentioned in the GraphQL specification, a query might result in some data and some errors, and those should be returned in a JSON object of the form:

{
  "data": { ... },
  "errors": [ ... ],
  "extensions": { ... }
}

如果没有返回任何错误,则 errors 字段不能出现在响应中。如果在执行开始之前发生错误,errors 字段必须包含这些错误,并且 data 字段不能出现在响应中。extensions 字段是可选的,此处提供的信息将由 GraphQL 实现自行决定。

¥If no errors were returned, the errors field must not be present in the response. If errors occurred before execution could start, the errors field must include these errors and the data field must not be present in the response. The extensions field is optional and information provided here will be at the discretion of the GraphQL implementation.

你可以在 响应页面 上阅读有关符合 GraphQL 规范的响应格式的更多信息。

¥You can read more about GraphQL spec-compliant response formats on the Response page.

状态代码

¥Status Codes

如果响应包含 data 键并且其值不是 null,则服务器应该使用 2xx 状态代码响应 application/graphql-response+jsonapplication/json 媒体类型。即使响应包含错误,情况也是如此,因为 HTTP 还没有代表 “部分成功。” 的状态代码

¥If a response contains a data key and its value is not null, then the server should respond with a 2xx status code for either the application/graphql-response+json or application/json media types. This is the case even if the response includes errors, since HTTP does not yet have a status code representing “partial success.”

对于阻止执行 GraphQL 操作的验证错误,服务器通常会发送 400 状态代码,尽管某些旧服务器在使用 application/json 媒体类型时可能会返回 2xx 状态代码。

¥For validation errors that prevent the execution of a GraphQL operation, the server will typically send a 400 status code, although some legacy servers may return a 2xx status code when the application/json media type is used.

对于使用 application/json 媒体类型响应的旧服务器,不鼓励对执行失败的有效 GraphQL 请求使用 4xx5xx 状态代码,但根据实现情况可能会使用。由于服务器端错误来源可能存在歧义,因此应改用此媒体类型中的 2xx 代码。

¥For legacy servers that respond with the application/json media type, the use of 4xx and 5xx status codes for valid GraphQL requests that fail to execute is discouraged but may be used depending on the implementation. Because of potential ambiguities regarding the source of the server-side error, a 2xx code should be used with this media type instead.

但是,对于具有 application/graphql-response+json 媒体类型的响应,如果有效的 GraphQL 请求执行失败,服务器将使用 4xx5xx 状态代码进行回复。

¥However, for responses with the application/graphql-response+json media type, the server will reply with a 4xx or 5xx status code if a valid GraphQL request fails to execute.

服务器实现

¥Server implementations

如果你使用 Node.js,我们建议你查看 JS 服务器实现列表

¥If you use Node.js, we recommend looking at the list of JS server implementations.

你可以查看 此处有以其他多种语言编写的服务器列表

¥You can view a list of servers written in many other languages here.

回顾

¥Recap

回顾这些关于通过 HTTP 提供 GraphQL 的建议:

¥To recap these recommendations for serving GraphQL over HTTP:

  • 在验证 GraphQL 请求之前,服务器应处理用户身份验证;授权应在 GraphQL 请求执行期间在你的业务逻辑内进行

    ¥The server should handle user authentication before a GraphQL request is validated; authorization should happen within your business logic during GraphQL request execution

  • GraphQL API 在单个端点上公开,通常以 /graphql 结尾

    ¥GraphQL APIs are exposed at a single endpoint, typically ending with /graphql

  • GraphQL 客户端和服务器应该支持 JSON,但也可能支持其他格式

    ¥GraphQL clients and servers should support JSON, but may support other formats

  • 客户端应在 application/graphql-response+jsonAccept 标头上指示媒体类型

    ¥Client should indicate a media type on the Accept header of application/graphql-response+json

  • GraphQL 请求使用 POST HTTP 方法发送,但查询操作也可以使用 GET 方法发送

    ¥GraphQL requests are sent using the POST HTTP method, but query operations may also be sent using the GET method

  • 客户端还应为 POST 请求提供值为 application/jsonContent-type 标头

    ¥Clients should also provide a Content-type header with a value of application/json for POST requests

  • 执行的 GraphQL 操作的全部或部分结果将在响应的 JSON 编码主体中的 data 键上提供,而有关验证或执行期间出现的任何错误的信息将在 errors 键上提供

    ¥The full or partial result of an executed GraphQL operation will be available on the data key in the JSON-encoded body of the response, while information about any errors raised during validation or execution will be available on the errors key

  • 失败的有效 GraphQL 操作的响应状态代码可能因响应所指示的媒体类型而异,但任何具有非空 data 键的 GraphQL 响应都将提供 2xx 响应

    ¥Response status codes for valid GraphQL operations that fail may vary depending on the indicated media type of the response, but any GraphQL response with a non-null data key will provide a 2xx response