Working with GraphQL over HTTP
1. Understanding HTTP Methods
| Method | Use |
|---|---|
| POST | All operations; body has query/variables |
| GET | Queries only (cacheable, idempotent) |
| Mutations via GET | Forbidden by spec |
2. Sending Query in Request Body
Example: POST request
fetch("/graphql", {
method: "POST",
headers: { "Content-Type": "application/json", "Accept": "application/graphql-response+json" },
body: JSON.stringify({
query: "query U($id: ID!) { user(id: $id) { name } }",
variables: { id: "1" },
operationName: "U"
})
});
3. Sending Query in URL
| Param | Encoding |
|---|---|
| query | URL-encoded |
| variables | JSON-encoded then URL-encoded |
| operationName | Plain string |
4. Setting Content-Type Header
| Header | Value |
|---|---|
| Request | application/json |
| Response (modern) | application/graphql-response+json |
| Response (legacy) | application/json |
| Multipart (defer/stream/uploads) | multipart/mixed |
5. Handling HTTP Status Codes
| Status | Meaning |
|---|---|
| 200 | Successful execution (may contain errors[]) |
| 400 | Malformed JSON / parse error |
| 401 / 403 | Auth issues (with graphql-response+json) |
| 405 | Method not allowed |
| 415 | Unsupported Content-Type |
| 429 | Rate limited |
| 500 | Internal server error |
6. Using Accept Header
| Accept | Behavior |
|---|---|
| application/graphql-response+json | Modern; status reflects errors |
| application/json | Legacy; always 200 on validation/exec errors |
| multipart/mixed | Enable @defer / @stream |
| text/event-stream | SSE subscriptions |
7. Implementing CORS
Example: Express CORS
import cors from "cors";
app.use(cors({
origin: ["https://app.example.com"],
credentials: true,
allowedHeaders: ["Content-Type", "Authorization", "Apollo-Require-Preflight"],
methods: ["POST", "GET", "OPTIONS"]
}));
8. Using GraphQL Endpoint
| Convention | Detail |
|---|---|
| Path | /graphql |
| Versioning | Avoid /v1/graphql; evolve schema instead |
| Subscriptions | /graphql upgrade to ws |
9. Batching HTTP Requests
| Format | Detail |
|---|---|
| Request body | Array of operation objects |
| Response | Parallel array of responses |
| Trade-off | Lower RTT cost; head-of-line blocking risk |
10. Implementing Compression
| Encoding | Detail |
|---|---|
| gzip | Wide support, decent ratio |
| brotli | Better ratio for text |
| Apply to | Both request (rare) and response (common) |