Back to Blog

OSDK TypeScript Frontend Integration Guide

coomia-dip provides not only powerful backend data processing and decision-making capabilities but also a type-safe Ontology access interface for frontend applications through OSDK (Ontology SDK). The TypeScript version of OSDK enables frontend developers to interact with Ontology entities as if they were local objects, with full TypeScript type inference and IDE autocompletion.

CoomiaPublished on January 27, 20264 min read
Share this articleTwitter / X

Series: S12 Developer Tutorials · Article 17 | Level: Intermediate | Reading Time: 15 min

OSDK TypeScript Frontend Integration Guide

#Introduction

coomia-dip provides not only powerful backend data processing and decision-making capabilities but also a type-safe Ontology access interface for frontend applications through OSDK (Ontology SDK). The TypeScript version of OSDK enables frontend developers to interact with Ontology entities as if they were local objects, with full TypeScript type inference and IDE autocompletion.

This tutorial walks you through code generation, React integration, and implementing core features including object queries, Action calls, and real-time subscriptions.

#1. OSDK Architecture Overview

#1.1 Code Generation Flow

OSDK uses code generation to automatically produce strongly-typed TypeScript client code from the Ontology Schema:

Code
Ontology Schema (Platform) -> osdk-cli generate -> Generated TypeScript Code
  +-- types/     # Object type definitions
  +-- objects/   # Object operation clients
  +-- actions/   # Action invocation clients
  +-- queries/   # OQL query clients
  +-- links/     # Link navigation

#1.2 Why Code Generation Over Runtime

  • Compile-time type safety: Property name typos caught at compile time
  • IDE autocompletion: Same dev experience as local TypeScript objects
  • Tree-shaking: Only used object types included in bundle
  • Zero runtime overhead: No reflection, no dynamic proxies

#2. Setup

#2.1 Install OSDK CLI

Bash
npm install -g @coomia-dip/osdk-cli
osdk --version

#2.2 Generate Client Code

Bash
osdk auth login --url http://localhost:8080 --token your-api-token
osdk generate typescript --output ./src/generated/ontology --package-name @app/ontology

#2.3 Initialize Client

TypeScript
import { OntoPlatformClient } from '@app/ontology/client';

export const ontologyClient = new OntoPlatformClient({
  baseUrl: import.meta.env.VITE_coomia-dip_URL || 'http://localhost:8080',
  auth: {
    type: 'oauth2',
    clientId: import.meta.env.VITE_OAUTH_CLIENT_ID,
    redirectUri: window.location.origin + '/callback',
  },
});

#3. Object Queries

#3.1 Basic Queries

TypeScript
// Get single object
const order = await ontologyClient.objects.Order.get('order-123');
console.log(order.productName);  // Full autocompletion
console.log(order.totalAmount);   // number type

// List with filters
const orders = await ontologyClient.objects.Order
  .where(o => o.status.eq('ACTIVE'))
  .where(o => o.totalAmount.gt(1000))
  .orderBy('createdAt', 'desc')
  .limit(20)
  .list();
TypeScript
const order = await ontologyClient.objects.Order.get('order-123');
const customer = await order.links.orderedBy.get();
console.log(`Customer: ${customer.name}`);

#3.3 Aggregation

TypeScript
const stats = await ontologyClient.objects.Order
  .where(o => o.createdAt.gte('2025-01-01'))
  .aggregate({
    totalRevenue: agg.sum('totalAmount'),
    orderCount: agg.count(),
  })
  .groupBy('status')
  .execute();

#4. React Integration

#4.1 With React Query

TypeScript
import { useQuery } from '@tanstack/react-query';

function useOrders(status: string) {
  return useQuery({
    queryKey: ['orders', status],
    queryFn: () => ontologyClient.objects.Order
      .where(o => o.status.eq(status))
      .orderBy('createdAt', 'desc')
      .list(),
  });
}

function OrderList() {
  const { data, isLoading } = useOrders('ACTIVE');
  if (isLoading) return <div>Loading...</div>;
  return (
    <table>
      <tbody>
        {data.data.map(order => (
          <tr key={order.orderId}>
            <td>{order.productName}</td>
            <td>${order.totalAmount.toFixed(2)}</td>
          </tr>
        ))}
      </tbody>
    </table>
  );
}

#4.2 Execute Actions

TypeScript
function useCreateOrder() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: (params: { customerId: string; productName: string; quantity: number }) =>
      ontologyClient.actions.CreateOrder.execute(params),
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['orders'] }),
  });
}

#4.3 Real-Time Subscriptions

TypeScript
function useRealtimeOrders() {
  const [orders, setOrders] = useState<Order[]>([]);
  useEffect(() => {
    const sub = ontologyClient.objects.Order
      .where(o => o.status.eq('ACTIVE'))
      .subscribe({
        onData: (event) => {
          if (event.type === 'CREATED') setOrders(prev => [event.object, ...prev]);
          else if (event.type === 'UPDATED')
            setOrders(prev => prev.map(o => o.orderId === event.object.orderId ? event.object : o));
          else if (event.type === 'DELETED')
            setOrders(prev => prev.filter(o => o.orderId !== event.object.orderId));
        },
      });
    return () => sub.unsubscribe();
  }, []);
  return orders;
}

#5. Advanced Features

#5.1 Batch Operations

TypeScript
const batch = ontologyClient.batch();
batch.objects.Order.update('order-1', { status: 'SHIPPED' });
batch.objects.Order.update('order-2', { status: 'SHIPPED' });
await batch.execute();

#5.2 OQL Custom Queries

TypeScript
const result = await ontologyClient.oql.execute<{
  orderId: string; customerName: string; totalAmount: number;
}>(`
  SELECT o.orderId, c.name AS customerName, o.totalAmount
  FROM Order o JOIN o.orderedBy c
  WHERE o.totalAmount > $1 LIMIT 10
`, [5000]);

#6. Testing

TypeScript
import { vi } from 'vitest';

vi.mock('./ontology/client', () => ({
  ontologyClient: {
    objects: {
      Order: {
        where: vi.fn().mockReturnThis(),
        list: vi.fn().mockResolvedValue({
          data: [{ orderId: 'O-1', productName: 'Widget', totalAmount: 100 }],
        }),
      },
    },
  },
}));

#Summary

This tutorial covered OSDK TypeScript integration: code generation, React integration with React Query, object queries, link navigation, aggregation, Action execution, real-time subscriptions, batch operations, and OQL custom queries. OSDK enables frontend developers to access the Ontology in a type-safe manner, dramatically improving development efficiency and code quality.

Next: [S12-18] Multi-Tenant Isolation & Configuration Guide Previous: [S12-16] Temporal Workflow Orchestration Guide