Skip to main content
Backends are the bridge between the LLM Gateway and your product data. The gateway defines clean interfaces that you implement to connect any data source.

Core Interfaces

ProductBackend

Handles product search, details, and inventory:
interface ProductBackend {
  // Search products with optional filters
  searchProducts(
    query: string,
    filters?: ProductFilters,
    options?: { limit?: number; offset?: number }
  ): Promise<ProductSearchResult>;
  
  // Get detailed product info by ID or slug
  getProductDetails(productId: string): Promise<Product | null>;
  
  // Check inventory for multiple products
  checkInventory(productIds: string[]): Promise<InventoryStatus[]>;
  
  // Get product recommendations
  getRecommendations(context: {
    productIds?: string[];
    userId?: string;
    strategy?: 'similar' | 'complementary' | 'trending' | 'personalized';
  }): Promise<Recommendation[]>;
}

CartBackend

Handles shopping cart operations:
interface CartBackend {
  // Create a new cart
  createCart(sessionId: string): Promise<Cart>;
  
  // Get existing cart
  getCart(cartId: string): Promise<Cart | null>;
  
  // Add item to cart
  addToCart(
    cartId: string,
    input: AddToCartInput
  ): Promise<{ cart: Cart; addedItem: CartItem }>;
  
  // Update item quantity
  updateCartItem(
    cartId: string,
    itemId: string,
    updates: { quantity?: number }
  ): Promise<Cart>;
  
  // Remove item from cart
  removeFromCart(cartId: string, itemId: string): Promise<Cart>;
  
  // Clear all items
  clearCart(cartId: string): Promise<void>;
}

OrderBackend

Handles order creation and management:
interface OrderBackend {
  // Create order from cart
  createOrder(
    cart: Cart,
    shippingAddress: ShippingAddress,
    paymentInfo?: PaymentInfo
  ): Promise<Order>;
  
  // Get order by ID
  getOrder(orderId: string): Promise<Order | null>;
  
  // Update order status
  updateOrderStatus(
    orderId: string,
    status: Order['status']
  ): Promise<Order>;
}

Type Definitions

Product

interface Product {
  id: string;
  name: string;
  description?: string;
  slug?: string;
  price: {
    amount: number;
    currency: string;
    compareAtPrice?: number;
  };
  imageUrl?: string;
  images?: string[];
  category?: string;
  tags?: string[];
  variants?: ProductVariant[];
  attributes?: Record<string, string>;
  inStock?: boolean;
  rating?: number;
  reviewCount?: number;
}

Implementation Examples

In-Memory Backend

Perfect for development and testing:
const products = [
  { id: '1', name: 'Product A', price: 29.99 },
  { id: '2', name: 'Product B', price: 49.99 },
];

const backend: ProductBackend = {
  async searchProducts(query) {
    const q = query.toLowerCase();
    const results = products.filter(p => 
      p.name.toLowerCase().includes(q)
    );
    return { products: results, total: results.length, hasMore: false };
  },
  // ... other methods
};

Database Backend (Prisma)

Connect to your existing database:
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

const backend: ProductBackend = {
  async searchProducts(query, filters, options) {
    const products = await prisma.product.findMany({
      where: {
        OR: [
          { name: { contains: query, mode: 'insensitive' } },
          { description: { contains: query, mode: 'insensitive' } },
        ],
        ...(filters?.category && { category: filters.category }),
        ...(filters?.priceMin && { price: { gte: filters.priceMin } }),
        ...(filters?.priceMax && { price: { lte: filters.priceMax } }),
      },
      take: options?.limit ?? 10,
      skip: options?.offset ?? 0,
    });
    
    return {
      products: products.map(mapProduct),
      total: products.length,
      hasMore: products.length === (options?.limit ?? 10),
    };
  },
  // ... other methods
};

Best Practices

You don’t need to implement everything. Start with ProductBackend, add CartBackend when needed.
The type definitions catch errors early and provide excellent IDE support.
Return null for not found items rather than throwing. Throw for actual errors.