Skip to main content
Learn how to call APIs type-safely using the generated Namespace Services.

Service Usage Overview

Namespace Calls

UserService.getUser() Concise syntax

Type Safe

Auto-completion Compile validation

Subset Support

Only needed fields Performance optimization

TanStack Query

useUser Hook Auto caching

Basic Usage

Service Import

Generated Services are exported as Namespaces from services.generated.ts.
Benefits of single file import:
  1. Consistency: All Services managed in one place
  2. Easy import: No need to find file paths
  3. Auto update: Auto-synced on pnpm generate
  4. Clear naming: Grouped by Namespace, no conflicts

Basic API Calls

Call Service static functions directly.
Features:
  • Async call with await
  • Response is auto-parsed (handled inside fetch function)
  • Types fully guaranteed
  • Subset parameter required (for getUser, etc.)
Namespace-based structure: - ❌ Class instance: No need for new UserService() - βœ… Static function: Call UserService.getUser() directly - All functions work independently

Understanding the Subset System

Sonamu’s core feature, the Subset system.
Why use Subset:
  1. Performance: Query only needed fields to reduce network cost
  2. Type safety: Returns accurate type for each Subset
  3. Explicitness: Clearly express what data is needed in code

Using in React

The easiest way is to use auto-generated TanStack Query Hooks.
Benefits of TanStack Query Hooks:
  • Auto caching (reuses same userId)
  • Auto revalidation (on focus, reconnection)
  • Auto loading/error state management
  • Auto duplicate request removal

Function Component (useEffect)

You can also call directly without using Hooks.
Recommended: Use TanStack Query Hooks when possible. They provide auto caching, revalidation, and state management, making code much more concise.

Event Handlers

Call APIs based on user actions.

Using Services in SSR

Sonamu supports SSR based on Vite + React. For SSR, use the SSR-specific Services automatically generated in queries.generated.ts.

What are SSR Services?

Separate from frontend Services (services.generated.ts), SSR-specific Services are automatically generated on the backend.

Using in registerSSR

Use these Services when registering SSR routes.

Frontend Service vs SSR Service

Key Difference: SSR Services execute backend Model methods directly without HTTP requests, eliminating network overhead.

Learn More

For detailed information about SSR, see the following documents.

Data Preloading

Preload data on the server with registerSSR

SSR Setup

Understand the SSR system

Understanding the Service Creation Mechanism

Services are Namespace-based static function collections.

Services are Namespaces, Not Classes

Namespace Characteristics:
  • Stateless: No instance creation needed
  • Static calls: Call UserService.getUser() directly
  • Type-safe: Full type inference via TypeScript Namespaces
  • Tree-shakable: Unused functions are excluded from the bundle

Services Have No Dependency Injection (DI)

Services are pure functions, so no dependencies are injected:
How is Context passed? Services pass Context via HTTP requests:
On the backend, Context is automatically extracted from the HTTP request:

Service Creation Process

Creation Steps:
  1. Backend: Write @api decorator on Model
  2. Sonamu Sync: Run pnpm sonamu sync
  3. Auto-generation: services.generated.ts file created
  4. Namespace Functions: Each API method converted to Namespace function
  5. Hook Generation: GET methods automatically generate useQuery Hooks

Where Are Model Instances?

Created directly in Server Components:
Why is new UserModel() safe?
  • Models are stateless, so creating new instances each time is safe
  • The constructor only initializes Subset queries
  • Context is dynamically retrieved via Sonamu.getContext()

Service vs Model Comparison

Cautions when creating Model instances: 1. Server Components only: Models cannot be imported in Client Components 2. Create each time: Singleton pattern unnecessary (stateless) 3. Context access: Sonamu.getContext() automatically retrieves from request context
Recommended patterns: - Client Component: Use Service - Server Component: Use Model directly - API endpoint: @api decorator on Model

Client Components

Services can be freely used in Client Components.

Error Handling

SonamuError Handling

Handle errors from Service calls in a type-safe manner.

Error Handling in React

Advanced Patterns

Parallel Requests

Call multiple APIs simultaneously to improve performance.
Performance comparison:
  • Sequential: 300ms + 200ms + 150ms = 650ms
  • Parallel: max(300ms, 200ms, 150ms) = 300ms

Subset Optimization

Choose appropriate Subset for the situation.

TanStack Query Utilization

Conditional Fetching

Cache Invalidation

Prefetching

Practical Example

Complete CRUD Flow

Cautions

Cautions when using Services: 1. Never manually modify generated Service files (services.generated.ts) 2. Subset parameter required: Must specify subset for getUser, etc. 3. In Server Components, call backend model directly instead of Service 4. Use isSonamuError() type guard for error handling 5. TanStack Query Hooks should only be called inside components 6. await keyword required (all Service functions are async) 7. It’s a Namespace so no new needed: Call UserService.getUser() directly

Next Steps

How Services Work

Understanding auto-generation

TanStack Query Hook

Easier with React

Authentication

Authentication system

Error Handling

Error handling patterns