Frontend Relay Integration
Relevant source files
The following files were used as context for generating this wiki page:
Introduction
The Frontend Relay Integration serves as the data fetching and state management backbone for the ProductCompare web application. It bridges the React-based frontend with the Elixir/Phoenix backend via a GraphQL API located at /api/graphql. This integration is designed to support both client-side interactivity and Server-Side Rendering (SSR) through a unified Relay environment.
The system utilizes Relay Modern to enforce strict data requirements through fragments and provides a standardized network layer for handling authentication, session persistence via cookies, and environment-specific API endpoint resolution. While the project currently supports manual fetch helpers in some routes, the architecture is transitioning towards a unified Relay-centric model to enable features like SSR store hydration and preloaded queries.
Sources: ARCHITECTURE.md:10-24, backend_starting_guide.md:144-149
Core Architecture
The integration consists of three primary layers: the Relay Environment, the Network Layer (Fetch GraphQL), and the Entry Points (Client and Server).
Relay Environment
The Relay Environment is the central hub that manages the local data store and the network interface. It is instantiated using createRelayEnvironment, which accepts an optional SSRContext to handle server-side specific data like request headers and cookies.
The diagram shows the branching logic for creating a Relay environment on the client versus the server, both feeding into a unified network layer.
Sources: assets/src/relay/environment.ts:11-23, assets/src/entry.server.tsx:10-15
Network Layer and Endpoint Resolution
The network layer uses fetchGraphQL to execute operations. It dynamically resolves the API endpoint based on the environment (Development vs. Production).
| Option | Type | Description |
|---|---|---|
VITE_API_BASE_URL | Environment Variable | The primary base URL for the GraphQL API. |
isDev | Boolean | Flag to determine if the app is in development mode. |
locationOrigin | String | Used in dev to target the local Phoenix server (defaulting to port 4000). |
Sources: assets/src/relay/fetch-graphql.ts:3-16, assets/src/relay/fetch-graphql.ts:70-82
Data Flow and SSR Integration
The integration is specifically designed to handle the complexities of Server-Side Rendering, ensuring that session state and cookies are correctly forwarded between the browser, the SSR server, and the GraphQL backend.
SSR Request Lifecycle
During a server render, the entry.server.tsx module creates a fresh Relay environment and passes a "trusted origin" and cookies to the GraphQL request. This ensures that the Phoenix-backed session remains the authority for authentication.
The sequence diagram illustrates the flow of a server-rendered request where cookies are proxied to the GraphQL API to maintain authentication.
Sources: assets/src/entry.server.tsx:10-33, assets/src/relay/fetch-graphql.ts:25-45, ARCHITECTURE.md:10-13
The SSR Context
The SSRContext interface is critical for maintaining consistency during the rendering lifecycle.
export interface SSRContext {
request?: Request;
headers?: Record<string, string>;
cookieString?: string;
}
Sources: assets/src/relay/fetch-graphql.ts:6-10
Configuration and Tooling
Relay is integrated into the build pipeline through Vite and the Relay Compiler.
- Compiler:
relay-compileris used to generate TypeScript types and optimized artifacts from GraphQL tags in the source code. - Runtime: The project uses
react-relayandrelay-runtimeversion^20.1.1. - SSR Streaming: The server uses
renderToReadableStreamfromreact-dom/serverwith a 10-second abort delay for streaming responses.
Sources: assets/package.json:9-17, assets/package.json:34-36, assets/src/entry.server.tsx:7-9
Implementation Details
fetchGraphQL Logic
The fetchGraphQL function is the core implementation of the Relay network fetcher. It handles:
- Header Management: Setting
content-type: application/json. - Credential Handling: Using
credentials: "include"on the client for browser-based session support, while using explicit header forwarding on the server. - Origin Validation: Resolving a trusted origin from request headers to prevent CSRF issues.
Sources: assets/src/relay/fetch-graphql.ts:20-68
Environment Creation
export function createRelayEnvironment(ssrContext?: SSRContext) {
return new Environment({
network: Network.create((params: RequestParameters, variables: Variables) => {
return fetchGraphQL(params.text!, variables as Record<string, unknown>, ssrContext);
}),
store: new Store(new RecordSource())
});
}
Sources: assets/src/relay/environment.ts:11-23
Summary
The Frontend Relay Integration provides a robust, type-safe data management layer for ProductCompare. By unifying client and server environments through a shared fetchGraphQL utility, it ensures that authentication state is preserved across SSR boundaries. The architecture utilizes Relay Modern's performance benefits while maintaining compatibility with the Phoenix backend's cookie-backed session authority.