Apso SDK

Usage

Methods and usage for an Apso Client

The ApsoClient provides an entity() method to interact with specific resources in the API. It allows you to chain different methods to build queries and perform CRUD operations.

entity(entityName: string): EntityClient

Creates an instance of EntityClient for the specified entity.

  • entityName: The name of the entity (e.g., 'users').

Example

const usersClient = apsoClient.entity('users');

where(filter: Record<string, any>): EntityClient

Adds a filter to the query.

  • filter: The filter conditions (e.g., { status: 'active' }).

Example

const activeUsers = await apsoClient.entity('users').where({ status: 'active' }).get();

join(joinTables: string[]): EntityClient

Adds joins to include related entities in the query response. This allows you to fetch associated data in a single request.

  • joinTables: An array of related entity names to join (e.g., ['profile', 'orders']).

Basic Join Example

// Fetch users with their profile information
const usersWithProfiles = await apsoClient.entity('users')
  .join(['profile'])
  .get();

Multiple Joins Example

// Fetch users with profiles, orders, and addresses
const usersWithRelatedData = await apsoClient.entity('users')
  .join(['profile', 'orders', 'addresses'])
  .where({ status: 'active' })
  .get();

Complex Join with Filtering

// Fetch orders with customer and product information, filtering by date
const recentOrdersWithDetails = await apsoClient.entity('orders')
  .join(['customer', 'products', 'shipping_address'])
  .where({ created_at: { gte: '2024-01-01' } })
  .orderBy({ created_at: 'DESC' })
  .limit(50)
  .get();

Nested Entity Joins

// Fetch companies with their departments and employees
const companiesWithStructure = await apsoClient.entity('companies')
  .join(['departments', 'departments.employees'])
  .where({ active: true })
  .get();

select(fields: string[]): EntityClient

Specifies which fields to return in the response. This is especially useful with joins to control the amount of data returned.

  • fields: An array of field names to include in the response.

Example with Joins

// Fetch users with specific fields from joined entities
const selectedUserData = await apsoClient.entity('users')
  .select(['id', 'name', 'email', 'profile.avatar', 'profile.bio', 'orders.id', 'orders.total'])
  .join(['profile', 'orders'])
  .where({ status: 'active' })
  .get();

limit(limit: number): EntityClient

Limits the number of returned records.

  • limit: The maximum number of records to return.

Example

const limitedUsers = await apsoClient.entity('users').where({ status: 'active' }).limit(10).get();

get<T>(): Promise<T>

Performs a GET request to retrieve the records.

Example

const users = await apsoClient.entity('users').where({ status: 'active' }).limit(10).get();

post<T>(data: any): Promise<T>

Performs a POST request to create a new resource.

  • data: The data to be sent in the request body.

Example

const newUser = await apsoClient.entity('users').post({ name: 'John Doe', email: 'john@example.com' });

put<T>(data: any): Promise<T>

Performs a PUT request to update an existing resource.

  • data: The data to be updated.

Example

const updatedUser = await apsoClient.entity('users').where({ id: 1 }).put({ email: 'john.doe@example.com' });

delete<T>(): Promise<T>

Performs a DELETE request to remove a resource.

Example

await apsoClient.entity('users').where({ id: 1 }).delete();

Real-World Join Examples

E-commerce Scenarios

Product Catalog with Categories and Reviews

// Fetch products with their categories, reviews, and inventory data
const productCatalog = await apsoClient.entity('products')
  .join(['category', 'reviews', 'inventory'])
  .select([
    'id', 'name', 'price', 'description',
    'category.name', 'category.slug',
    'reviews.rating', 'reviews.comment', 'reviews.user_name',
    'inventory.quantity', 'inventory.warehouse_location'
  ])
  .where({ status: 'active', 'inventory.quantity': { gt: 0 } })
  .orderBy({ created_at: 'DESC' })
  .limit(20)
  .get();

Order Management with Full Details

// Fetch orders with customer, items, and shipping information
const orderDetails = await apsoClient.entity('orders')
  .join(['customer', 'order_items', 'order_items.product', 'shipping_address', 'payment_method'])
  .select([
    'id', 'order_number', 'status', 'total', 'created_at',
    'customer.name', 'customer.email', 'customer.phone',
    'order_items.quantity', 'order_items.price',
    'order_items.product.name', 'order_items.product.sku',
    'shipping_address.street', 'shipping_address.city', 'shipping_address.postal_code',
    'payment_method.type', 'payment_method.last_four'
  ])
  .where({ status: { in: ['pending', 'processing'] } })
  .orderBy({ created_at: 'DESC' })
  .get();

Content Management Scenarios

Blog Posts with Authors and Comments

// Fetch blog posts with author details and recent comments
const blogPostsWithDetails = await apsoClient.entity('posts')
  .join(['author', 'comments', 'comments.user', 'tags'])
  .select([
    'id', 'title', 'slug', 'content', 'published_at',
    'author.name', 'author.bio', 'author.avatar',
    'comments.content', 'comments.created_at',
    'comments.user.name', 'comments.user.avatar',
    'tags.name', 'tags.slug'
  ])
  .where({ published: true })
  .orderBy({ published_at: 'DESC' })
  .limit(10)
  .get();

User Management Scenarios

User Profiles with Permissions and Activity

// Fetch users with their roles, permissions, and recent activity
const userManagement = await apsoClient.entity('users')
  .join(['profile', 'roles', 'roles.permissions', 'activity_logs'])
  .select([
    'id', 'username', 'email', 'status', 'last_login',
    'profile.first_name', 'profile.last_name', 'profile.department',
    'roles.name', 'roles.description',
    'roles.permissions.resource', 'roles.permissions.action',
    'activity_logs.action', 'activity_logs.timestamp'
  ])
  .where({ status: 'active' })
  .orderBy({ last_login: 'DESC' })
  .get();

Query Parameters

The SDK supports several query parameters for GET requests to filter, sort, or paginate data.

Available Query Methods

  • where(filter: Record<string, any>): Filter records (e.g., { active: true }).
  • join(joinTables: string[]): Include related entities in the response.
  • select(fields: string[]): Specify which fields to return.
  • limit(limit: number): Limit the number of returned records.
  • offset(offset: number): Skip a number of records.
  • page(page: number): Specify the page number for pagination.
  • orderBy(sort: Record<string, 'ASC' | 'DESC'>): Sort the results.
  • or(orCondition: Record<string, any>): Add OR conditions to the query.
  • cache(useCache?: boolean, duration?: number): Enable caching for the request.

Advanced Query Example

const result = await apsoClient.entity('users')
  .select(['id', 'name', 'email', 'profile.avatar', 'orders.total'])
  .join(['profile', 'orders'])
  .where({ active: true, 'profile.verified': true })
  .or({ role: 'admin' })
  .orderBy({ created_at: 'DESC' })
  .limit(25)
  .offset(50)
  .cache(true, 300) // Cache for 5 minutes
  .get();

Error Handling

The ApsoClient will throw an error if the request fails. Make sure to wrap your requests in try-catch blocks to handle errors appropriately.

try {
  const userWithOrders = await apsoClient.entity('users')
    .join(['orders', 'profile'])
    .where({ id: 1 })
    .get();
  console.log(userWithOrders);
} catch (error) {
  console.error('Error fetching user with related data:', error);
}