

# Examples and patterns
<a name="examples"></a>

This topic shows common application patterns you can build with AWS Blocks. Each example demonstrates how Blocks compose together to solve real-world problems.

For more information about runnable sample applications, see [AWS Blocks example applications on GitHub](https://github.com/aws-devtools-labs/aws-blocks/tree/main/examples).

## CRUD API with authentication
<a name="example-crud-api"></a>

A typical data-driven application with user authentication and scoped data access.

```
import { ApiNamespace, Scope, KVStore, AuthBasic } from '@aws-blocks/blocks';

const scope = new Scope('notes-app');
const auth = new AuthBasic(scope, 'auth');
const notes = new KVStore(scope, 'notes', {});

export const api = new ApiNamespace(scope, 'api', (context) => ({
  async create(title: string, body: string) {
    const user = await auth.getCurrentUser(context);
    const id = crypto.randomUUID();
    const note = { id, title, body, createdAt: Date.now() };
    await notes.set(`${user.userId}:${id}`, note);
    return note;
  },

  async list() {
    const user = await auth.getCurrentUser(context);
    return notes.list({ prefix: `${user.userId}:` });
  },

  async delete(id: string) {
    const user = await auth.getCurrentUser(context);
    await notes.delete(`${user.userId}:${id}`);
  },
}));

export { auth };
```

 **Blocks used:** `AuthBasic`, `KVStore`, `ApiNamespace` 

## Real-time chat
<a name="example-realtime-chat"></a>

A chat application with WebSocket pub/sub and message history.

```
import { ApiNamespace, Scope, KVStore, AuthBasic, Realtime } from '@aws-blocks/blocks';
import { z } from 'zod';

const scope = new Scope('chat-app');
const auth = new AuthBasic(scope, 'auth');
const messages = new KVStore(scope, 'messages', {});

const messageSchema = z.object({ id: z.string(), user: z.string(), text: z.string(), ts: z.number() });

const realtime = new Realtime(scope, 'realtime', {
  namespaces: { chat: Realtime.namespace(messageSchema) },
});

export const api = new ApiNamespace(scope, 'api', (context) => ({
  async sendMessage(text: string) {
    const user = await auth.getCurrentUser(context);
    const msg = { id: crypto.randomUUID(), user: user.userId, text, ts: Date.now() };
    await messages.set(`msg:${msg.id}`, msg);
    await realtime.publish('chat', 'general', msg);
    return msg;
  },

  async getHistory() {
    return messages.list({ prefix: 'msg:' });
  },
}));

export { auth, realtime };
```

### Frontend integration
<a name="frontend-integration"></a>

The frontend subscribes to real-time updates:

```
import { api, realtime, auth } from '../aws-blocks/index.js';

// Authenticate
await auth.signIn('user@example.com', 'password', context);

// Subscribe to messages
const channel = await realtime.getChannel('chat', 'general');
channel.subscribe((msg) => {
  console.log(`${msg.user}: ${msg.text}`);
});

// Send a message
await api.sendMessage('Hello, world!');

// Load history
const history = await api.getHistory();
```

 **Blocks used:** `AuthBasic`, `KVStore`, `Realtime`, `ApiNamespace` 

## File uploads with metadata
<a name="example-file-uploads"></a>

An application that stores files with associated metadata.

```
import { ApiNamespace, Scope, KVStore, FileBucket, AuthBasic } from '@aws-blocks/blocks';

const scope = new Scope('files-app');
const auth = new AuthBasic(scope, 'auth');
const files = new FileBucket(scope, 'uploads');
const metadata = new KVStore(scope, 'file-metadata', {});

export const api = new ApiNamespace(scope, 'api', (context) => ({
  async upload(name: string, data: Buffer) {
    const user = await auth.getCurrentUser(context);
    const key = `${user.userId}/${name}`;
    await files.put(key, data);
    await metadata.set(key, { name, size: data.length, uploadedAt: Date.now() });
    return { key };
  },

  async listFiles() {
    const user = await auth.getCurrentUser(context);
    return metadata.list({ prefix: `${user.userId}/` });
  },

  async download(key: string) {
    const user = await auth.getCurrentUser(context);
    if (!key.startsWith(`${user.userId}/`)) throw new Error('Forbidden');
    return files.get(key);
  },
}));

export { auth };
```

 **Blocks used:** `AuthBasic`, `FileBucket`, `KVStore`, `ApiNamespace` 

## SQL-backed application
<a name="example-sql-app"></a>

An application using relational data with joins and transactions.

```
import { ApiNamespace, Scope, Database, AuthBasic, sql } from '@aws-blocks/blocks';

const scope = new Scope('store-app');
const auth = new AuthBasic(scope, 'auth');
const db = new Database(scope, 'db');

export const api = new ApiNamespace(scope, 'api', (context) => ({
  async createOrder(items: Array<{ productId: string; qty: number }>) {
    const user = await auth.getCurrentUser(context);

    return db.transaction(async (trx) => {
      const [order] = await trx.query(sql`
        INSERT INTO orders (user_id, status, created_at)
        VALUES (${user.userId}, 'pending', NOW())
        RETURNING *
      `);

      for (const item of items) {
        await trx.execute(sql`
          INSERT INTO order_items (order_id, product_id, quantity)
          VALUES (${order.id}, ${item.productId}, ${item.qty})
        `);
      }

      return order;
    });
  },

  async getOrders() {
    const user = await auth.getCurrentUser(context);
    return db.query(sql`
      SELECT * FROM orders
      WHERE user_id = ${user.userId}
      ORDER BY created_at DESC
    `);
  },
}));

export { auth };
```

 **Blocks used:** `AuthBasic`, `Database`, `ApiNamespace` 

## Common patterns
<a name="example-patterns-summary"></a>


| Pattern | Approach | 
| --- | --- | 
| User-scoped data | Prefix keys with `${user.userId}:` to isolate data per user | 
| Optimistic UI | Return the created/updated object from API methods so the frontend can update immediately | 
| Background work | Use the CDK layer to add SQS queues or EventBridge rules alongside Blocks | 
| Multi-tenant | Use Scope IDs or key prefixes to partition data by tenant | 
| Feature flags | Store flags in a `KVStore` and read them in API methods before executing logic | 

## Related resources
<a name="examples-further-reading"></a>

For more information about runnable sample applications with frontend code, deployment instructions, and tests:
+  [AWS Blocks example applications on GitHub](https://github.com/aws-devtools-labs/aws-blocks/tree/main/examples) 
+  [AWS Blocks project templates](https://github.com/aws-devtools-labs/aws-blocks/tree/main/templates) used by `npm create @aws-blocks/blocks-app@latest` 