通过 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).
operationName
、variables
和 extensions
参数是可选字段。仅当 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+json
或 application/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 请求使用 4xx
和 5xx
状态代码,但根据实现情况可能会使用。由于服务器端错误来源可能存在歧义,因此应改用此媒体类型中的 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 请求执行失败,服务器将使用 4xx
或 5xx
状态代码进行回复。
¥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+json
的Accept
标头上指示媒体类型¥Client should indicate a media type on the
Accept
header ofapplication/graphql-response+json
-
GraphQL 请求使用
POST
HTTP 方法发送,但查询操作也可以使用GET
方法发送¥GraphQL requests are sent using the
POST
HTTP method, but query operations may also be sent using theGET
method -
客户端还应为
POST
请求提供值为application/json
的Content-type
标头¥Clients should also provide a
Content-type
header with a value ofapplication/json
forPOST
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 theerrors
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 a2xx
response