Skip to main content

CRUD Operations

Master the four fundamental database operations: Create, Read, Update, and Delete across all platforms.
CRUD operations are the building blocks of any application. Cocobase makes them simple, intuitive, and consistent across all languages.

Overview

Cocobase provides type-safe, efficient CRUD operations for all supported platforms:
  • Create - Add new documents to collections
  • Read - Retrieve documents by ID or with filters
  • Update - Modify existing documents (partial or full)
  • Delete - Remove documents from collections
  • Batch Operations - Perform multiple operations at once

Create Documents

Add new documents to your collections with automatic ID generation and timestamp tracking.

Basic Creation

import { Cocobase } from 'cocobase';

const db = new Cocobase({ apiKey: 'your-api-key' });

// Create a single document with timestamps
const user = await db.createDocument('users', {
  name: 'John Doe',
  email: 'john@example.com',
  age: 30,
  active: true,
  createdAt: new Date().toISOString(),
  updatedAt: new Date().toISOString()
});

console.log('Created user:', user.id);

Type-Safe Creation

interface User {
  name: string;
  email: string;
  age: number;
  active: boolean;
}

const user = await db.createDocument<User>('users', {
  name: 'Jane Smith',
  email: 'jane@example.com',
  age: 28,
  active: true
});

// TypeScript knows the structure
console.log(user.data.name); // ✓ Type-safe

Batch Creation

Create multiple documents in a single operation for better performance.

const users = await db.createDocuments('users', [
  {
    name: 'Alice',
    email: 'alice@example.com',
    age: 25,
    createdAt: new Date().toISOString(),
    updatedAt: new Date().toISOString()
  },
  {
    name: 'Bob',
    email: 'bob@example.com',
    age: 32,
    createdAt: new Date().toISOString(),
    updatedAt: new Date().toISOString()
  },
  {
    name: 'Charlie',
    email: 'charlie@example.com',
    age: 28,
    createdAt: new Date().toISOString(),
    updatedAt: new Date().toISOString()
  }
]);

console.log(`Created ${users.length} users`);

Read Documents

Retrieve documents by ID, or query collections with filters and pagination.

Get Single Document


const user = await db.getDocument('users', 'user-123');
console.log(user.data);

List All Documents

const allUsers = await db.listDocuments('users');
console.log(`Total users: ${allUsers.length}`);

With Filters

// Get active users
const activeUsers = await db.listDocuments('users', {
  filters: { active: true }
});

// Get users older than 25
const olderUsers = await db.listDocuments('users', {
  filters: { age_gte: 25 }
});

// Multiple filters (AND logic)
const specificUsers = await db.listDocuments('users', {
  filters: {
    active: true,
    age_gte: 25,
    age_lte: 40
  }
});

With Pagination

// First page (10 users)
const page1 = await db.listDocuments('users', { limit: 10, offset: 0 });

// Second page
const page2 = await db.listDocuments('users', { limit: 10, offset: 10 });

// Helper for any page
function getPage(pageNumber, pageSize = 10) {
  return db.listDocuments('users', {
    limit: pageSize,
    offset: (pageNumber - 1) * pageSize
  });
}

const page3 = await getPage(3); // Users 21-30
``
</Tab>

<Tab title="Dart">
```dart
// Get first page (10 users)
final page1 = await db.listDocuments('users', filters: {
  'limit': 10,
  'offset': 0,
});

// Get second page
final page2 = await db.listDocuments('users', filters: {
  'limit': 10,
  'offset': 10,
});

// Using QueryBuilder
final page3 = await db.listDocuments(
  'users',
  queryBuilder: QueryBuilder().limit(10).offset(20),
);

Update Documents

Modify existing documents with partial or full updates.

Basic Update


// Partial update
await db.updateDocument('users', 'user-123', {
  age: 31,
  active: false,
  updatedAt: new Date().toISOString()
});

console.log('User updated');
Updates are partial by default - you only need to provide the fields you want to change. Other fields remain unchanged.

Batch Update

await db.updateDocuments('users', {
  'user-1': { age: 31, updatedAt: new Date().toISOString() },
  'user-2': { age: 29, updatedAt: new Date().toISOString() },
  'user-3': { active: false, updatedAt: new Date().toISOString() }
});

Delete Documents

Remove documents from collections permanently.

Delete Single Document

await db.deleteDocument('users', 'user-123');
console.log('User deleted');```
</Tab>

<Tab title="Dart">
```dart
await db.deleteDocument('users', 'user-123');
print('User deleted');

Batch Delete


const idsToDelete = ['user-1', 'user-2', 'user-3'];
const result = await db.deleteDocuments('users', idsToDelete);
console.log(`Deleted ${result.count} documents`);
Instead of permanently deleting, mark documents as deleted for recovery options.

// Mark as deleted instead of permanent removal
await db.updateDocument('users', 'user-123', {
  deleted: true,
  deletedAt: new Date().toISOString(),
  updatedAt: new Date().toISOString()
});

// Query non-deleted
const activeUsers = await db.listDocuments('users', {
  filters: { deleted: false }
});
``
</Tab>

<Tab title="Dart">
```dart
// Mark as deleted
await db.updateDocument('users', 'user-123', {
  'deleted': true,
  'deletedAt': DateTime.now().toIso8601String(),
});

// Query non-deleted items
final activeUsers = await db.listDocuments('users', filters: {
  'deleted': false,
});

Error Handling

Handle errors gracefully across all operations.

try {
  const user = await db.getDocument('users', 'user-123');
  console.log(user.data);
} catch (error) {
  // Cocobase error structure might include statusCode
  if (error?.statusCode === 404) {
    console.error('Document not found');
  } else if (error?.statusCode === 401) {
    console.error('Unauthorized: Invalid API key');
  } else if (error?.statusCode === 403) {
    console.error('Permission denied');
  } else {
    console.error('Unexpected error:', error.message || error);
  }
}

Best Practices

Define your data structures for better development experience and fewer bugs.
// ✓ Good: Type-safe
interface User {
  name: string;
  email: string;
}

const user = await db.createDocument<User>('users', {
  name: 'John',
  email: 'john@example.com'
});
Always wrap operations in try-catch blocks or check for errors.
// ✓ Good: Error handling
try {
  const user = await db.getDocument('users', userId);
  console.log(user);
} catch (error) {
  console.error('Failed to fetch user:', error.message);
}
Batch operations are more efficient than multiple individual requests.
// ✓ Good: Single batch operation
await db.createDocuments('users', [user1, user2, user3]);

// ✗ Bad: Multiple individual operations
await db.createDocument('users', user1);
await db.createDocument('users', user2);
await db.createDocument('users', user3);
Use soft deletes for important data to enable recovery.
// ✓ Good: Soft delete
await db.updateDocument('users', userId, {
  deleted: true,
  deletedAt: new Date().toISOString()
});
Track when records are created and modified.
// ✓ Good: Include timestamps
const post = await db.createDocument('posts', {
  title: 'My Post',
  content: '...',
  createdAt: new Date().toISOString(),
  updatedAt: new Date().toISOString()
});

Next Steps