### Install Apollo Server Fastify Integration Source: https://github.com/apollo-server-integrations/apollo-server-integration-fastify/blob/main/readme.md Installs the necessary packages for integrating Apollo Server with Fastify, including the integration package itself, Apollo Server, GraphQL, and Fastify. ```bash npm install @as-integrations/fastify @apollo/server graphql fastify ``` -------------------------------- ### Basic Fastify and Apollo Server Setup Source: https://github.com/apollo-server-integrations/apollo-server-integration-fastify/blob/main/readme.md Demonstrates the basic setup of Fastify and Apollo Server, registering the `fastifyApollo` plugin to connect them. It's crucial to call and await `apollo.start()` before registering the plugin. ```typescript import Fastify from "fastify"; import { ApolloServer, BaseContext } from "@apollo/server"; import fastifyApollo, { fastifyApolloDrainPlugin } from "@as-integrations/fastify"; // ... const fastify = Fastify(); const apollo = new ApolloServer({ typeDefs, resolvers, plugins: [fastifyApolloDrainPlugin(fastify)], }); await apollo.start(); // ... await fastify.register(fastifyApollo(apollo)); ``` -------------------------------- ### ApolloFastifyPluginOptions Interface (TypeScript) Source: https://github.com/apollo-server-integrations/apollo-server-integration-fastify/blob/main/readme.md Extends `ApolloFastifyHandlerOptions` to provide additional configuration for the Apollo Server Fastify plugin. It allows setting the GraphQL endpoint path and the allowed HTTP methods. The default path is '/graphql' and methods include GET, POST, and OPTIONS. ```typescript interface ApolloFastifyPluginOptions extends ApolloFastifyHandlerOptions { path?: string; // default: "/graphql" method?: HTTPMethod | HTTPMethod[]; // default: ["GET", "POST", "OPTIONS"] } ``` -------------------------------- ### Fastify Apollo Server Production Setup (TypeScript) Source: https://context7.com/apollo-server-integrations/apollo-server-integration-fastify/llms.txt Sets up an Apollo Server instance integrated with Fastify. It configures middleware such as helmet, cors, compress, and rate limiting. Includes custom error formatting and logging for GraphQL requests, along with a health check endpoint. Dependencies: @apollo/server, @as-integrations/fastify, @fastify/compress, @fastify/cors, @fastify/helmet, @fastify/rate-limit, fastify, pino-pretty. ```typescript import { ApolloServer } from "@apollo/server"; import fastifyApollo, { fastifyApolloDrainPlugin, ApolloFastifyContextFunction } from "@as-integrations/fastify"; import compress from "@fastify/compress"; import cors from "@fastify/cors"; import helmet from "@fastify/helmet"; import rateLimit from "@fastify/rate-limit"; import Fastify from "fastify"; // Context interface interface AppContext { requestId: string; userId: string | null; startTime: number; } // GraphQL schema const typeDefs = ` type Query { products(limit: Int = 10): [Product!]! product(id: ID!): Product } type Product { id: ID! name: String! price: Float! inStock: Boolean! } `; // Mock database const products = [ { id: "1", name: "Laptop", price: 999.99, inStock: true }, { id: "2", name: "Mouse", price: 29.99, inStock: true }, { id: "3", name: "Keyboard", price: 79.99, inStock: false } ]; // Resolvers with error handling const resolvers = { Query: { products: (_, { limit }, context: AppContext) => { console.log(`Request ${context.requestId}: Fetching ${limit} products`); return products.slice(0, limit); }, product: (_, { id }, context: AppContext) => { const product = products.find(p => p.id === id); if (!product) { throw new Error(`Product with id ${id} not found`); } return product; } } }; // Context function with request tracking const contextFunction: ApolloFastifyContextFunction = async (request, reply) => { const authHeader = request.headers.authorization; const userId = authHeader ? authHeader.replace("Bearer ", "") : null; return { requestId: request.id, userId, startTime: Date.now() }; }; // Initialize Fastify with configuration const fastify = Fastify({ logger: { level: "info", transport: { target: "pino-pretty" } }, requestIdHeader: "x-request-id", requestIdLogLabel: "reqId" }); // Initialize Apollo Server const apollo = new ApolloServer({ typeDefs, resolvers, plugins: [fastifyApolloDrainPlugin(fastify)], formatError: (formattedError, error) => { // Log errors console.error("GraphQL Error:", formattedError); // Customize error response return { ...formattedError, message: formattedError.message, extensions: { ...formattedError.extensions, timestamp: new Date().toISOString() } }; } }); await apollo.start(); // Register middleware plugins await fastify.register(helmet, { contentSecurityPolicy: { directives: { defaultSrc: ["'self'"], styleSrc: ["'self'", "'unsafe-inline'"] } } }); await fastify.register(cors, { origin: ["http://localhost:3000", "https://app.example.com"], credentials: true }); await fastify.register(compress, { encodings: ["gzip", "deflate"] }); await fastify.register(rateLimit, { max: 100, timeWindow: "1 minute" }); // Register Apollo plugin await fastify.register(fastifyApollo(apollo), { path: "/graphql", method: ["POST", "OPTIONS"], context: contextFunction }); // Health check endpoint fastify.get("/health", async () => ({ status: "ok", timestamp: new Date().toISOString() })); // Start server const port = parseInt(process.env.PORT || "4000", 10); const host = process.env.HOST || "0.0.0.0"; await fastify.listen({ port, host }); console.log(`GraphQL server running at http://${host}:${port}/graphql`); // Example requests: // curl -X POST http://localhost:4000/graphql \ // -H "Content-Type: application/json" \ // -d '{"query":"{ products { id name price inStock } }"}' // // curl -X POST http://localhost:4000/graphql \ // -H "Content-Type: application/json" \ // -d '{"query":"{ product(id: \"1\") { name price } }"}' ``` -------------------------------- ### Register Apollo Server with Fastify using fastifyApollo Plugin Source: https://context7.com/apollo-server-integrations/apollo-server-integration-fastify/llms.txt This snippet demonstrates how to register an Apollo Server instance with a Fastify application using the `fastifyApollo` plugin. It shows default registration and custom configuration for the GraphQL endpoint path and HTTP methods. The Apollo Server must be started before registering the plugin. ```typescript import Fastify from "fastify"; import { ApolloServer } from "@apollo/server"; import fastifyApollo, { fastifyApolloDrainPlugin } from "@as-integrations/fastify"; // Define GraphQL schema const typeDefs = ` type Query { users: [User!]! user(id: ID!): User } type User { id: ID! name: String! email: String! } `; // Define resolvers const resolvers = { Query: { users: () => [ { id: "1", name: "John Doe", email: "john@example.com" }, { id: "2", name: "Jane Smith", email: "jane@example.com" } ], user: (_, { id }) => ({ id, name: "John Doe", email: "john@example.com" }) } }; // Initialize Fastify server const fastify = Fastify(); // Create Apollo Server instance const apollo = new ApolloServer({ typeDefs, resolvers, plugins: [fastifyApolloDrainPlugin(fastify)] }); // Start Apollo Server (required before plugin registration) await apollo.start(); // Register the plugin with default options (POST/GET/OPTIONS on /graphql) await fastify.register(fastifyApollo(apollo)); // Or with custom options await fastify.register(fastifyApollo(apollo), { path: "/api/graphql", method: ["POST", "OPTIONS"] }); // Start Fastify server await fastify.listen({ port: 4000 }); console.log("Server running at http://localhost:4000/graphql"); ``` -------------------------------- ### Accessing Custom Context in Apollo Resolvers Source: https://github.com/apollo-server-integrations/apollo-server-integration-fastify/blob/main/readme.md Demonstrates how to access the custom context, previously defined by `myContextFunction`, within Apollo Server resolvers. This example shows checking for authorization before returning data. ```typescript // Access the context in your resolvers export const resolvers = { Query: { helloWorld: (parent, args, context, info) => { if (!context.authorization) { throw new Error("Not authorized"); } return "Hello world :)"; }, }, }; ``` -------------------------------- ### Apollo Server Fastify Handler Options Source: https://github.com/apollo-server-integrations/apollo-server-integration-fastify/blob/main/readme.md Options for configuring the Apollo Server handler within a Fastify application. ```APIDOC ## ApolloFastifyHandlerOptions ### Description Options for configuring the Apollo Server handler within a Fastify application. ### Parameters #### Request Body - **context** (ApolloFastifyContextFunction) - Optional - A function to provide context to the GraphQL execution. Defaults to an async function returning an empty object. ### Request Example ```json { "context": "async () => ({ user: 'test' })" } ``` ### Response #### Success Response (200) - **data** (object) - The result of the GraphQL query. - **errors** (array) - An array of errors encountered during execution, if any. #### Response Example ```json { "data": { "hello": "world" } } ``` ``` -------------------------------- ### Fastify Apollo Handler for Route Configuration Source: https://github.com/apollo-server-integrations/apollo-server-integration-fastify/blob/main/readme.md Shows how to use `fastifyApolloHandler` to integrate Apollo Server within Fastify routes, allowing explicit configuration of URL paths and HTTP methods. ```typescript import { fastifyApolloHandler } from "@as-integrations/fastify"; // ... setup Fastify & Apollo fastify.post("/graphql", fastifyApolloHandler(apollo)); // OR fastify.get("/api", fastifyApolloHandler(apollo)); // OR fastify.route({ url: "/graphql", method: ["POST", "OPTIONS"], handler: fastifyApolloHandler(apollo), }); ``` -------------------------------- ### Apollo Server Fastify Plugin Options Source: https://github.com/apollo-server-integrations/apollo-server-integration-fastify/blob/main/readme.md Options for configuring the Apollo Server plugin within a Fastify application. ```APIDOC ## ApolloFastifyPluginOptions ### Description Options for configuring the Apollo Server plugin within a Fastify application. This interface extends `ApolloFastifyHandlerOptions`. ### Parameters #### Query Parameters - **path** (string) - Optional - The endpoint path for GraphQL requests. Defaults to "/graphql". - **method** (HTTPMethod | HTTPMethod[]) - Optional - The HTTP methods allowed for GraphQL requests. Defaults to `["GET", "POST", "OPTIONS"]`. ### Request Example ```json { "path": "/api/graphql", "method": ["POST", "OPTIONS"] } ``` ### Response #### Success Response (200) - **data** (object) - The result of the GraphQL query. - **errors** (array) - An array of errors encountered during execution, if any. #### Response Example ```json { "data": { "users": [] } } ``` ``` -------------------------------- ### fastifyApollo Plugin Source: https://context7.com/apollo-server-integrations/apollo-server-integration-fastify/llms.txt The main plugin function that registers Apollo Server with a Fastify instance, automatically creating a route handler at a specified path with configurable HTTP methods. It simplifies the integration by handling route creation and configuration. ```APIDOC ## fastifyApollo Plugin ### Description Registers Apollo Server with a Fastify instance, automatically creating a route handler at a specified path with configurable HTTP methods. Supports custom context functions and flexible routing. ### Method `fastify.register` ### Endpoint Configurable via plugin options (`path` option, defaults to `/graphql`) ### Parameters #### Plugin Options - **apolloServer** (ApolloServer) - Required - An instance of Apollo Server. - **path** (string) - Optional - The GraphQL endpoint path. Defaults to `/graphql`. - **method** (string[]) - Optional - Allowed HTTP methods for the GraphQL endpoint. Defaults to `['POST', 'GET', 'OPTIONS']`. ### Request Example ```typescript import Fastify from "fastify"; import { ApolloServer } from "@apollo/server"; import fastifyApollo, { fastifyApolloDrainPlugin } from "@as-integrations/fastify"; const fastify = Fastify(); const apollo = new ApolloServer({ typeDefs, resolvers }); await apollo.start(); // Register with default options await fastify.register(fastifyApollo(apollo)); // Register with custom options await fastify.register(fastifyApollo(apollo), { path: "/api/graphql", method: ["POST", "OPTIONS"] }); ``` ### Response #### Success Response (200) Apollo Server handles GraphQL responses, typically returning JSON payloads for query/mutation results or streaming responses for subscriptions. #### Response Example ```json { "data": { "users": [ { "id": "1", "name": "John Doe", "email": "john@example.com" }, { "id": "2", "name": "Jane Smith", "email": "jane@example.com" } ] } } ``` ``` -------------------------------- ### Implement Graceful Shutdown Plugin for Apollo Server Fastify Source: https://context7.com/apollo-server-integrations/apollo-server-integration-fastify/llms.txt This TypeScript code illustrates the use of `fastifyApolloDrainPlugin` for graceful server shutdown in a Fastify and Apollo Server integration. This plugin is crucial for containerized environments like Kubernetes, ensuring that active connections are drained before the server terminates. It requires `@apollo/server`, `@as-integrations/fastify`, and `fastify`. The plugin hooks into the server lifecycle to manage shutdown signals. ```typescript import { ApolloServer } from "@apollo/server"; import { fastifyApolloDrainPlugin } from "@as-integrations/fastify"; import Fastify from "fastify"; const typeDefs = ` type Query { longRunningOperation: String! } `; const resolvers = { Query: { longRunningOperation: async () => { // Simulate long-running operation await new Promise(resolve => setTimeout(resolve, 5000)); return "Operation completed"; } } }; const fastify = Fastify({ logger: true, // Force close connections after grace period forceCloseConnections: true }); const apollo = new ApolloServer({ typeDefs, resolvers, // Add drain plugin to handle graceful shutdown plugins: [fastifyApolloDrainPlugin(fastify)] }); await apollo.start(); await fastify.register(fastifyApollo(apollo)); await fastify.listen({ port: 4000 }); // Handle shutdown signals gracefully process.on("SIGTERM", async () => { console.log("SIGTERM received, shutting down gracefully..."); await fastify.close(); console.log("Server closed"); process.exit(0); }); // The drain plugin will: // 1. Stop accepting new requests // 2. Wait up to 10 seconds for active requests to complete // 3. Close all remaining connections // 4. Shut down the server ``` -------------------------------- ### Attach Apollo Server Handler to Fastify Route using fastifyApolloHandler Source: https://context7.com/apollo-server-integrations/apollo-server-integration-fastify/llms.txt This snippet shows how to use `fastifyApolloHandler` to attach an Apollo Server to a specific Fastify route. It allows for fine-grained control over the route's path and HTTP methods. This approach is useful for creating multiple GraphQL endpoints or when more complex route configurations are needed. ```typescript import Fastify from "fastify"; import { ApolloServer } from "@apollo/server"; import { fastifyApolloHandler } from "@as-integrations/fastify"; const typeDefs = ` type Query { status: String! } `; const resolvers = { Query: { status: () => "API is running" } }; const fastify = Fastify(); const apollo = new ApolloServer({ typeDefs, resolvers }); await apollo.start(); // Attach handler to specific route with POST only fastify.post("/graphql", fastifyApolloHandler(apollo)); // Multiple GraphQL endpoints with different paths fastify.post("/api/v1/graphql", fastifyApolloHandler(apollo)); fastify.post("/api/v2/graphql", fastifyApolloHandler(apollo)); // Using Fastify's route method for full control fastify.route({ url: "/graphql", method: ["POST", "OPTIONS"], handler: fastifyApolloHandler(apollo) }); await fastify.listen({ port: 4000 }); ``` -------------------------------- ### ApolloFastifyHandlerOptions Interface (TypeScript) Source: https://github.com/apollo-server-integrations/apollo-server-integration-fastify/blob/main/readme.md Defines the options for configuring the Apollo Server handler within a Fastify application. It allows customization of the request context. The default context is an empty object. ```typescript interface ApolloFastifyHandlerOptions { context?: ApolloFastifyContextFunction; // default: async () => ({}) } ``` -------------------------------- ### Implement Custom Context Function for Apollo Server Fastify Source: https://context7.com/apollo-server-integrations/apollo-server-integration-fastify/llms.txt This TypeScript code demonstrates how to create a custom context function for Apollo Server integrated with Fastify. It enables passing request-scoped data, such as user authentication status and request IDs, to GraphQL resolvers. Dependencies include `@apollo/server`, `@as-integrations/fastify`, and `fastify`. The function takes Fastify's request and reply objects as input and returns a context object conforming to a defined interface. ```typescript import { ApolloServer } from "@apollo/server"; import fastifyApollo, { ApolloFastifyContextFunction } from "@as-integrations/fastify"; import Fastify from "fastify"; // Define custom context interface interface MyContext { userId: string | null; isAuthenticated: boolean; requestId: string; } // Mock authentication function async function validateToken(token?: string): Promise { if (token === "valid-token-123") { return "user-456"; } return null; } // Create context function with authentication logic const myContextFunction: ApolloFastifyContextFunction = async (request, reply) => { const authHeader = request.headers.authorization; const token = authHeader?.replace("Bearer ", ""); const userId = await validateToken(token); return { userId, isAuthenticated: userId !== null, requestId: request.id }; }; // Define schema with protected queries const typeDefs = ` type Query { me: User publicData: String! } type User { id: ID! name: String! } `; // Resolvers that use context for authorization const resolvers = { Query: { me: (parent, args, context: MyContext) => { if (!context.isAuthenticated) { throw new Error("Authentication required"); } return { id: context.userId, name: "Authenticated User" }; }, publicData: () => "This is public" } }; const fastify = Fastify(); const apollo = new ApolloServer({ typeDefs, resolvers }); await apollo.start(); // Register with context function await fastify.register(fastifyApollo(apollo), { context: myContextFunction }); await fastify.listen({ port: 4000 }); // Test authenticated request: // curl -X POST http://localhost:4000/graphql \ // -H "Content-Type: application/json" \ // -H "Authorization: Bearer valid-token-123" \ // -d '{"query":"{ me { id name } }"}' ``` -------------------------------- ### Custom Context Function for Apollo Server in Fastify Source: https://github.com/apollo-server-integrations/apollo-server-integration-fastify/blob/main/readme.md Illustrates how to define and use a custom context function with `fastifyApollo` or `fastifyApolloHandler`. This function processes the Fastify request and reply objects to create a custom context for Apollo Server resolvers. ```typescript import { ApolloServer } from "@apollo/server"; import fastifyApollo, { fastifyApolloHandler, ApolloFastifyContextFunction, } from "@as-integrations/fastify"; // ... interface MyContext { authorization: JWTPayload | false; } const apollo = new ApolloServer(...); const myContextFunction: ApolloFastifyContextFunction = async (request, reply) => ({ authorization: await isAuthorized(request.headers.authorization), }); await fastify.register(fastifyApollo(apollo), { context: myContextFunction, }); // OR await fastify.post("/graphql", fastifyApolloHandler(apollo, { context: myContextFunction, })); ``` -------------------------------- ### fastifyApolloHandler Route Handler Source: https://context7.com/apollo-server-integrations/apollo-server-integration-fastify/llms.txt A standalone route handler function that can be attached to any Fastify route, providing fine-grained control over GraphQL endpoint configuration. This allows for custom routing and method configurations. ```APIDOC ## fastifyApolloHandler Route Handler ### Description A standalone route handler function that can be attached to any Fastify route, providing fine-grained control over GraphQL endpoint configuration. Use this when you need to attach the GraphQL handler to a specific route with custom configurations. ### Method `fastify.post`, `fastify.route` (or any HTTP method handler) ### Endpoint Any custom endpoint path defined by the user. ### Parameters #### Handler Function - **apolloServer** (ApolloServer) - Required - An instance of Apollo Server. #### Fastify Route Options (when using `fastify.route`) - **url** (string) - Required - The endpoint path. - **method** (string[]) - Optional - Allowed HTTP methods for the endpoint. - **handler** (function) - Required - The route handler, which is `fastifyApolloHandler(apolloServer)`. ### Request Example ```typescript import Fastify from "fastify"; import { ApolloServer } from "@apollo/server"; import { fastifyApolloHandler } from "@as-integrations/fastify"; const fastify = Fastify(); const apollo = new ApolloServer({ typeDefs, resolvers }); await apollo.start(); // Attach handler to specific route with POST only fastify.post("/graphql", fastifyApolloHandler(apollo)); // Using Fastify's route method for full control fastify.route({ url: "/api/graphql", method: ["POST", "OPTIONS"], handler: fastifyApolloHandler(apollo) }); ``` ### Response #### Success Response (200) Apollo Server handles GraphQL responses, typically returning JSON payloads for query/mutation results or streaming responses for subscriptions. #### Response Example ```json { "data": { "status": "API is running" } } ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.