API Library Overview
The @elcto/api package provides unified REST, GraphQL, and WebSocket clients for Heimdall platform applications.
Installation
The library is already included in both platform/id and platform/backend. For new Next.js apps in the monorepo:
- Add the dependency to
package.json:
{
"dependencies": {
"@elcto/api": "workspace:*"
}
}
- Add to
next.config.ts:
const nextConfig: NextConfig = {
transpilePackages: ['@elcto/api', '@elcto/ui'],
};
- Run
pnpm install
Quick Start
REST API
import { apiRequest } from "@/lib/api";
// GET request
const response = await apiRequest<User>("/v1/users/123");
if (response.data) {
console.log(response.data);
}
// POST request
const result = await apiRequest<void>("/v1/users", {
method: "POST",
body: { name: "John" },
});
GraphQL
import { gql, graphqlRequest } from "@/lib/api";
// Using gql helper (throws on error)
const data = await gql<{ user: User }>(`
query GetUser($id: ID!) {
user(id: $id) {
id
name
}
}
`, { id: "123" });
// Using raw request (returns errors)
const response = await graphqlRequest<{ user: User }>(query, variables);
if (response.errors) {
console.error(response.errors);
}
WebSocket (Client-side only)
import { createWebSocket } from "@/lib/api";
const ws = createWebSocket("/v1/ws/user", {
accessToken: session.accessToken,
autoReconnect: true,
});
ws.onMessage((data) => {
if (data.type === "accountBanned") {
// Handle ban
}
});
ws.send({ type: "ping" });
ws.close();
React Hook
import { useWebSocket } from "@/lib/api";
function LiveUpdates() {
const { isConnected, lastMessage, send } = useWebSocket("/v1/ws/updates", {
accessToken: session.accessToken,
});
return (
<div>
<p>Status: {isConnected ? "Connected" : "Disconnected"}</p>
<button onClick={() => send({ type: "ping" })}>Ping</button>
</div>
);
}
Authentication
Server-side (REST & GraphQL)
The library automatically uses SYSTEM_API_KEY for server-side requests:
// Automatically uses SYSTEM_API_KEY if available
const response = await apiRequest<User>("/v1/users/123");
// Or provide a specific access token
const response = await apiRequest<User>("/v1/users/123", {
accessToken: userAccessToken,
});
Priority: accessToken option > SYSTEM_API_KEY > no auth
Client-side (WebSocket)
WebSocket connections require an access token passed via config:
const ws = createWebSocket("/v1/ws/user", {
accessToken: session.accessToken,
});
Environment Variables
| Variable | Description | Default |
|---|---|---|
NEXT_PUBLIC_API_URL | API base URL | http://localhost:3000 |
NEXT_PUBLIC_WS_URL | WebSocket URL | Derived from API URL |
SYSTEM_API_KEY | Server-side API key | - |
Package Structure
shared/api/
├── src/
│ ├── index.ts # Main exports
│ ├── config.ts # Configuration utilities
│ ├── clients/
│ │ ├── rest.ts # REST client
│ │ ├── graphql.ts # GraphQL client
│ │ └── websocket.ts # WebSocket client
│ ├── types/
│ │ ├── audit.ts # Audit types & constants
│ │ ├── common.ts # Common types (pagination, config)
│ │ ├── discord.ts # Discord integration types
│ │ ├── graphql.ts # GraphQL types
│ │ ├── integration.ts # Integration types
│ │ ├── rest.ts # REST types
│ │ ├── session.ts # Session types
│ │ ├── user.ts # User types
│ │ └── websocket.ts # WebSocket types & messages
│ ├── routes/
│ │ ├── audit.ts # Audit log routes
│ │ ├── sessions.ts # Session management routes
│ │ └── users.ts # User API routes
│ ├── hooks/
│ │ └── useWebSocket.ts # React WebSocket hook
│ ├── constants/
│ │ └── roles.ts # Role constants & helpers
│ └── errors/
│ └── index.ts # Error handler & codes
Next Steps
- REST Client - Complete REST API reference
- GraphQL Client - GraphQL client reference
- WebSocket Client - WebSocket client reference
- Error Handling - Consistent error responses
- Pre-built Routes - User, session, and audit routes
- Types - Type definitions reference