Skip to content

Commit b6ffbba

Browse files
Copilothotlong
andcommitted
Add complete MSW + React CRUD example with ObjectStack Client
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent acbdc35 commit b6ffbba

File tree

15 files changed

+1368
-0
lines changed

15 files changed

+1368
-0
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Dependencies
2+
node_modules
3+
pnpm-lock.yaml
4+
5+
# Build outputs
6+
dist
7+
build
8+
*.tsbuildinfo
9+
10+
# Development
11+
.vite
12+
.cache
13+
14+
# Environment
15+
.env
16+
.env.local
17+
18+
# Editor
19+
.vscode/*
20+
!.vscode/extensions.json
21+
.idea
22+
*.swp
23+
*.swo
24+
*~
25+
26+
# OS
27+
.DS_Store
28+
Thumbs.db
29+
30+
# MSW
31+
public/mockServiceWorker.js
Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
# MSW + React CRUD Example
2+
3+
This example demonstrates complete CRUD operations in a React application using **Mock Service Worker (MSW)** for API mocking and the **@objectstack/client** package for all data operations.
4+
5+
## 🎯 Features
6+
7+
-**Complete CRUD Operations**: Create, Read, Update, Delete tasks
8+
-**ObjectStack Client Integration**: Uses official `@objectstack/client` for all API calls
9+
-**MSW API Mocking**: All API requests are intercepted and mocked in the browser
10+
-**React + TypeScript**: Modern React with full TypeScript support
11+
-**Vite**: Fast development server and build tool
12+
-**Best Practices**: Follows ObjectStack conventions and patterns
13+
14+
## 📁 Project Structure
15+
16+
```
17+
src/
18+
├── components/
19+
│ ├── TaskForm.tsx # Create/Update form component
20+
│ ├── TaskItem.tsx # Single task display component
21+
│ └── TaskList.tsx # Task list with read operations
22+
├── mocks/
23+
│ └── browser.ts # MSW handlers and mock database
24+
├── App.tsx # Main application component
25+
├── App.css # Application styles
26+
├── main.tsx # Entry point with MSW initialization
27+
└── types.ts # TypeScript type definitions
28+
```
29+
30+
## 🚀 Getting Started
31+
32+
### Prerequisites
33+
34+
- Node.js 18+
35+
- pnpm (package manager)
36+
37+
### Installation
38+
39+
```bash
40+
# Install dependencies
41+
pnpm install
42+
43+
# Initialize MSW service worker (required for browser mode)
44+
pnpm dlx msw init public/ --save
45+
```
46+
47+
### Running the Application
48+
49+
```bash
50+
# Start development server
51+
pnpm dev
52+
```
53+
54+
The application will be available at `http://localhost:3000`
55+
56+
### Building for Production
57+
58+
```bash
59+
# Build the application
60+
pnpm build
61+
62+
# Preview the production build
63+
pnpm preview
64+
```
65+
66+
## 📖 How It Works
67+
68+
### 1. MSW Setup (`src/mocks/browser.ts`)
69+
70+
MSW intercepts HTTP requests in the browser and returns mock data:
71+
72+
```typescript
73+
import { setupWorker } from 'msw/browser';
74+
import { http, HttpResponse } from 'msw';
75+
76+
// Define handlers matching ObjectStack API
77+
const handlers = [
78+
http.get('/api/v1/data/task', () => {
79+
return HttpResponse.json({ value: tasks, count: tasks.length });
80+
}),
81+
82+
http.post('/api/v1/data/task', async ({ request }) => {
83+
const body = await request.json();
84+
const newTask = { id: generateId(), ...body };
85+
return HttpResponse.json(newTask, { status: 201 });
86+
}),
87+
88+
// ... more handlers
89+
];
90+
91+
export const worker = setupWorker(...handlers);
92+
```
93+
94+
### 2. ObjectStack Client Usage
95+
96+
All components use the official `@objectstack/client` package:
97+
98+
```typescript
99+
import { ObjectStackClient } from '@objectstack/client';
100+
101+
// Initialize client
102+
const client = new ObjectStackClient({ baseUrl: '/api/v1' });
103+
await client.connect();
104+
105+
// READ - Find all tasks
106+
const result = await client.data.find('task', {
107+
top: 100,
108+
sort: ['priority']
109+
});
110+
111+
// CREATE - Create new task
112+
const newTask = await client.data.create('task', {
113+
subject: 'New task',
114+
priority: 1
115+
});
116+
117+
// UPDATE - Update existing task
118+
await client.data.update('task', taskId, {
119+
isCompleted: true
120+
});
121+
122+
// DELETE - Delete task
123+
await client.data.delete('task', taskId);
124+
```
125+
126+
### 3. React Components
127+
128+
**TaskList Component** (`src/components/TaskList.tsx`)
129+
- Fetches and displays all tasks
130+
- Demonstrates READ operations
131+
- Handles task deletion and status toggling
132+
133+
**TaskForm Component** (`src/components/TaskForm.tsx`)
134+
- Form for creating new tasks
135+
- Form for editing existing tasks
136+
- Demonstrates CREATE and UPDATE operations
137+
138+
**TaskItem Component** (`src/components/TaskItem.tsx`)
139+
- Displays individual task
140+
- Provides edit and delete actions
141+
- Shows task metadata (priority, completion status)
142+
143+
## 🔌 API Endpoints Mocked
144+
145+
The example mocks the following ObjectStack API endpoints:
146+
147+
| Method | Endpoint | Description |
148+
|--------|----------|-------------|
149+
| `GET` | `/api/v1` | Discovery endpoint |
150+
| `GET` | `/api/v1/meta/object/task` | Get task object metadata |
151+
| `GET` | `/api/v1/data/task` | Find/list all tasks |
152+
| `GET` | `/api/v1/data/task/:id` | Get single task by ID |
153+
| `POST` | `/api/v1/data/task` | Create new task |
154+
| `PATCH` | `/api/v1/data/task/:id` | Update existing task |
155+
| `DELETE` | `/api/v1/data/task/:id` | Delete task |
156+
157+
## 🎨 UI Features
158+
159+
- **Priority Indicators**: Color-coded priority levels (1-5)
160+
- **Completion Status**: Checkbox to mark tasks as complete
161+
- **Real-time Updates**: Automatic list refresh after CRUD operations
162+
- **Responsive Design**: Works on desktop and mobile devices
163+
- **Loading States**: Shows loading indicators during async operations
164+
- **Error Handling**: Displays error messages for failed operations
165+
166+
## 📚 Key Concepts
167+
168+
### MSW (Mock Service Worker)
169+
170+
MSW intercepts requests at the network level, making it ideal for:
171+
- Development without a backend
172+
- Testing components in isolation
173+
- Demos and prototypes
174+
- Offline development
175+
176+
### ObjectStack Client
177+
178+
The `@objectstack/client` provides a type-safe, consistent API for:
179+
- Auto-discovery of server capabilities
180+
- Metadata operations
181+
- Data CRUD operations
182+
- Query operations with filters, sorting, and pagination
183+
184+
### Best Practices Demonstrated
185+
186+
1. **Single Source of Truth**: All API calls go through ObjectStack Client
187+
2. **Type Safety**: Full TypeScript support with proper interfaces
188+
3. **Component Separation**: Clear separation between data fetching and presentation
189+
4. **Error Handling**: Proper error handling and user feedback
190+
5. **Loading States**: Visual feedback during async operations
191+
192+
## 🔧 Customization
193+
194+
### Adding New Fields
195+
196+
1. Update the `Task` interface in `src/types.ts`
197+
2. Update mock handlers in `src/mocks/browser.ts`
198+
3. Update components to display/edit new fields
199+
200+
### Changing Mock Data
201+
202+
Edit the initial data in `src/mocks/browser.ts`:
203+
204+
```typescript
205+
const mockTasks = new Map([
206+
['1', { id: '1', subject: 'Your task', priority: 1, ... }],
207+
// Add more tasks...
208+
]);
209+
```
210+
211+
### Styling
212+
213+
All styles are in `src/App.css`. The design uses CSS custom properties (variables) for easy theming.
214+
215+
## 📦 Dependencies
216+
217+
- **@objectstack/client** - Official ObjectStack client SDK
218+
- **@objectstack/plugin-msw** - MSW integration for ObjectStack
219+
- **react** - UI library
220+
- **msw** - Mock Service Worker for API mocking
221+
- **vite** - Build tool and dev server
222+
- **typescript** - Type safety
223+
224+
## 🤝 Related Examples
225+
226+
- [`/examples/msw-demo`](../../../msw-demo) - MSW plugin integration examples
227+
- [`/examples/todo`](../../../todo) - Todo app with ObjectStack Client
228+
- [`/examples/ui/react-renderer`](../react-renderer) - React metadata renderer
229+
230+
## 📖 Further Reading
231+
232+
- [MSW Documentation](https://mswjs.io/)
233+
- [ObjectStack Client API](../../packages/client)
234+
- [ObjectStack Protocol Specification](../../packages/spec)
235+
- [React Documentation](https://react.dev/)
236+
237+
## 📝 License
238+
239+
Apache-2.0
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>ObjectStack MSW + React CRUD Example</title>
8+
</head>
9+
<body>
10+
<div id="root"></div>
11+
<script type="module" src="/src/main.tsx"></script>
12+
</body>
13+
</html>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"name": "@objectstack/example-msw-react-crud",
3+
"version": "1.0.0",
4+
"description": "Complete MSW integration example with React CRUD components using ObjectStack Client",
5+
"private": true,
6+
"type": "module",
7+
"scripts": {
8+
"dev": "vite",
9+
"build": "tsc && vite build",
10+
"preview": "vite preview"
11+
},
12+
"dependencies": {
13+
"@objectstack/client": "workspace:*",
14+
"@objectstack/plugin-msw": "workspace:*",
15+
"@objectstack/spec": "workspace:*",
16+
"react": "^18.3.1",
17+
"react-dom": "^18.3.1"
18+
},
19+
"devDependencies": {
20+
"@types/react": "^18.3.1",
21+
"@types/react-dom": "^18.3.0",
22+
"@vitejs/plugin-react": "^4.3.4",
23+
"msw": "^2.0.0",
24+
"typescript": "^5.0.0",
25+
"vite": "^5.4.11"
26+
}
27+
}

0 commit comments

Comments
 (0)