GraphQL API Design
Relevant source files
The following files were used as context for generating this wiki page:
The GraphQL API serves as the primary interface for mobile and web clients within the LiveCanvas ecosystem. It is designed to handle durable reads and writes, facilitating features such as account management, social interactions, content delivery, and live session orchestration. The API follows a modular monolith architecture where specific domain boundaries—Accounts, Social, Content, Live, Chat, and Feed—are exposed through a unified schema.
Sources: ARCHITECTURE.md:27-31, ARCHITECTURE.md:126-128
The implementation follows a Relay-first philosophy, emphasizing the use of the Node interface for global object identification and the Connection pattern for standardized cursor-based pagination. This ensures a consistent developer experience across different resource types and supports efficient data fetching for mobile clients.
Sources: AGENTS.md:10-10, mobile/schema.graphql:28-31
Core Design Principles
The GraphQL API is built upon several foundational architectural rules to ensure security, scalability, and maintainability.
Relay-First Architecture
The API strictly adheres to Relay specifications. This includes:
- Global IDs: Every major entity implements the
Nodeinterface, providing a uniqueidfor refetching. - Connections and Edges: List-based data is returned via
Connectiontypes, which includeedges(containing the node and cursor) andPageInfo(for pagination metadata). - Cursor Pagination: All feeds and lists use
afterandfirstarguments for forward pagination.
Sources: AGENTS.md:10-10, mobile/schema.graphql:525-533
Authorization and Security
Authorization is applied at the resolver level. Viewer authorization is re-applied in node fetchers and child field resolvers to prevent Insecure Direct Object Reference (IDOR) vulnerabilities (CWE-639). Even with globally refetchable IDs, the system ensures that ownership and visibility rules (such as private account restrictions) are strictly enforced.
Sources: AGENTS.md:11-11, ARCHITECTURE.md:225-231
This diagram illustrates the layered authorization flow where social relationship checks override direct resource access.
Sources: ARCHITECTURE.md:225-231, AGENTS.md:11-11
Schema Structure
The API is divided into a RootQueryType for data retrieval and a RootMutationType for state-changing operations.
Root Queries
The query entry points are primarily viewer-centric or feed-oriented.
| Field | Type | Description |
|---|---|---|
viewer | User | Returns the currently authenticated user. |
node(id: ID!) | Node | Fetches any object by its global unique ID. |
homeFeed | PostConnection | Retrieves the personalized home timeline. |
liveNow | LiveSessionConnection | Lists currently active live sessions. |
relationshipState | RelationshipState | Checks follow/block status between viewer and a creator. |
Sources: mobile/schema.graphql:6-25
Root Mutations
Mutations are grouped by functional domains such as Auth, Social, and Live.
| Category | Key Mutations |
|---|---|
| Auth | beginAuthChallenge, signUp, logIn, refreshAuthTokens |
| Content | createPost, updatePost, deletePost, requestMediaUpload |
| Social | followUser, blockUser, muteUser, acceptFollowRequest |
| Live | startLiveSession, goLiveSession, joinLiveSession, endLiveSession |
Sources: mobile/schema.graphql:33-68
Domain Specifics
Live Session Orchestration
The GraphQL API manages the lifecycle of live sessions. A host initiates a session via startLiveSession, which creates a record in a STARTING state. The session moves to LIVE once media negotiation (coordinated via WebSockets/Channels) is complete.
Sources: ARCHITECTURE.md:144-152, mobile/schema.graphql:218-243
This sequence shows the transition of a live session from initialization to the active state.
Sources: ARCHITECTURE.md:144-152, mobile/schema.graphql:102-120
Content and Media
Content is handled via the Post type, which supports different kinds like STANDARD or STORY. Media assets are uploaded through a two-step process:
- Request: The client calls
requestMediaUploadwith a MIME type. - Signed URL: The API returns a
SignedUploadobject containing a URL and headers for direct object storage upload.
Sources: mobile/schema.graphql:275-283, mobile/schema.graphql:332-343
Technical Implementation Details
Data Types and Enums
The schema defines several enums to enforce strict state transitions and visibility rules.
- LiveSessionStatus:
STARTING,LIVE,ENDED. - PostVisibility:
FOLLOWERS,PUBLIC. - MediaProcessingState:
PENDING_UPLOAD,UPLOADED,PROCESSED,FAILED.
Sources: mobile/schema.graphql:206-216, mobile/schema.graphql:255-260
Connection Pattern Example
Pagination is standardized. The PageInfo type provides the necessary metadata for the client to determine if more data is available.
type PageInfo {
hasPreviousPage: Boolean!
hasNextPage: Boolean!
startCursor: String
endCursor: String
}
Sources: mobile/schema.graphql:525-533
Client-Side Integration
Mobile clients use the GraphQL API for all durable state. For example, the home.tsx screen logic navigates users to profile or live-session routes which subsequently perform GraphQL queries to populate their respective views. Real-time updates (like live chat messages or session transitions) are typically handled via Phoenix Channels, complementing the GraphQL durables.
Sources: mobile/app/(app)/home.tsx:18-31, ARCHITECTURE.md:130-138, assets/js/app.js:23-27
Conclusion
The GraphQL API design for LiveCanvas provides a robust, Relay-compliant interface that separates durable data management from ephemeral real-time state. By enforcing modular boundaries and strict authorization at the resolver level, it ensures a secure and scalable foundation for social and live streaming features.