|
| 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 |
0 commit comments