Frontend API Integration
Relevant source files
The following files were used as context for generating this wiki page:The frontend, built with Next.js, communicates with the FastAPI backend through a combination of RESTful API calls for standard operations and a WebSocket connection for real-time updates. This hybrid approach allows for efficient data fetching and state management, providing a dynamic and responsive user experience on the Q&A platform.
All API and WebSocket configurations are centralized, and communication is managed through React components and context providers. Authentication is handled via JWT tokens, which are included in the headers of protected requests.
Sources: web/src/config/api.js, web/src/context/WebSocketContext.js, README.md:10-13
Core Configuration
The central point of configuration for all frontend-to-backend communication is located in web/src/config/api.js. This file defines the base URLs for the API and WebSockets, enumerates all API endpoints, and provides a helper function for creating authenticated request headers.
Sources: web/src/config/api.js
Environment Variables
The base URLs for the HTTP API and WebSocket connections are configured via environment variables, allowing for easy switching between development and production environments.
| Variable | Description | Default Value |
|---|---|---|
NEXT_PUBLIC_API_BASE_URL | The base URL for all REST API calls. | http://localhost:8000 |
NEXT_PUBLIC_WS_BASE_URL | The base URL for the WebSocket connection. | ws://localhost:8000 |
Sources: web/src/config/api.js:2-3, README.md:200-201
API Endpoints
An API_ENDPOINTS object centralizes all API paths, making them easy to manage and reference throughout the application.
// web/src/config/api.js:6-25
export const API_ENDPOINTS = {
// Auth
REGISTER: '/auth/register',
LOGIN: '/auth/login',
GET_ME: '/auth/me',
// Questions
GET_QUESTIONS: '/questions',
CREATE_QUESTION: '/questions',
GET_QUESTION: (id) => `/questions/${id}`,
UPDATE_QUESTION: (id) => `/questions/${id}`,
SUGGEST_ANSWER: (id) => `/questions/${id}/suggest-answer`,
CHECK_DUPLICATE: '/questions/check-duplicate',
// Answers
CREATE_ANSWER: (questionId) => `/answers/${questionId}`,
GET_ANSWERS: (questionId) => `/answers/${questionId}`,
DELETE_ANSWER: (answerId) => `/answers/${answerId}`,
// WebSocket
WS: '/ws',
};
This structure includes static paths and dynamic functions for endpoints that require an ID.
Sources: web/src/config/api.js:6-25
Authentication Headers
The getAuthHeaders function is a utility that constructs the necessary headers for API requests. It sets the Content-Type to application/json and, if a JWT token is provided, adds the Authorization header with the Bearer token. This function is used in almost every API call that requires user authentication.
// web/src/config/api.js:28-36
export const getAuthHeaders = (token) => {
const headers = {
'Content-Type': 'application/json',
};
if (token) {
headers['Authorization'] = `Bearer ${token}`;
}
return headers;
};
The token itself is managed by the AuthContext and stored in localStorage to persist user sessions.
Sources: web/src/config/api.js:28-36, web/src/context/AuthContext.js:11-17
REST API Communication
Standard user actions such as logging in, registering, and posting questions/answers are handled via REST API calls using the browser's fetch API.
User Authentication
The authentication flow begins on the login or registration pages. When a user logs in, the frontend sends a POST request to the /auth/login endpoint. Upon success, the backend returns a JWT access_token and user data, which are then stored in localStorage via the AuthContext.
The following diagram illustrates the login sequence.
This diagram shows the user submitting credentials, the API call being made, and the successful response being used to update the application's authentication state.
Sources: web/src/app/login/page.js:46-62, web/src/context/AuthContext.js:30-35
Core Features (Questions & Answers)
Creating a new question is a common action that demonstrates the API integration. The QuestionForm component sends a POST request to the /questions endpoint with the question message in the body and the user's auth token in the headers.
The diagram below shows the flow for posting a new question.
After the question is successfully created in the database, the backend broadcasts a question_created event via the WebSocket server, which triggers a real-time update on all connected clients' UIs.
Sources: web/src/components/QuestionForm.js:71-92, backend/api/questions.py:46-52
Other interactions, such as fetching answers for a question or updating a question's status, follow a similar pattern of making authenticated fetch requests to the appropriate endpoints defined in api.js.
Sources: web/src/components/QuestionCard.js:37-51, web/src/components/QuestionCard.js:86-98
Real-Time Communication with WebSockets
To ensure the UI is always up-to-date with the latest questions and status changes, the application uses a WebSocket connection managed by the WebSocketContext.
Sources: web/src/context/WebSocketContext.js
Connection Management
The WebSocketProvider is responsible for establishing and maintaining the connection. It attempts to connect to the /questions/ws endpoint as soon as it's mounted. It also includes logic for automatic reconnection on disconnect.
The following diagram illustrates the connection lifecycle.
This flow ensures a persistent connection is attempted, providing a resilient real-time experience.
Sources: web/src/context/WebSocketContext.js:16-49
Handling Real-Time Events
Once connected, the WebSocketContext listens for incoming messages from the server. The server sends messages with a type and data payload. The context updates its internal questions state based on the message type.
| Message Type | Description |
|---|---|
questions_list | Sent on initial connection. Contains the full list of all questions. |
question_created | Sent when a new question is posted. The new question is prepended to the list. |
question_updated | Sent when a question's status is changed. The corresponding question in the list is updated. |
The following diagram shows how a real-time update is processed.
This mechanism allows the UI to reflect changes made by any user in real-time without requiring manual refreshes or polling.
Sources: web/src/context/WebSocketContext.js:29-43, backend/api/questions.py:127-134
Summary
The frontend API integration in the QA-Dashboard is robust and efficient, leveraging a dual-communication strategy. REST APIs handle user-initiated, state-changing actions like authentication and content creation. Simultaneously, WebSockets provide a live, real-time feed of new questions and status updates, ensuring the application state is always synchronized with the backend. This architecture is made clean and maintainable through centralized configuration and state management via React Context.