Skip to main content

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:

  1. Add the dependency to package.json:
{
"dependencies": {
"@elcto/api": "workspace:*"
}
}
  1. Add to next.config.ts:
const nextConfig: NextConfig = {
transpilePackages: ['@elcto/api', '@elcto/ui'],
};
  1. 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

VariableDescriptionDefault
NEXT_PUBLIC_API_URLAPI base URLhttp://localhost:3000
NEXT_PUBLIC_WS_URLWebSocket URLDerived from API URL
SYSTEM_API_KEYServer-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