Highly ambitious ATProtocol AppView service and sdks
1# Core Concepts
2
3Slices is built on four fundamental concepts that work together to create a
4powerful AT Protocol development platform.
5
6```
7Slices → Lexicons → Sync → APIs
8(Container) → (Schema) → (Data) → (Access)
9```
10
11## **Slices**: Your Data Universe
12
13### What is a Slice?
14
15A slice is your own independent data space within the AT Protocol network. Think
16of it as a database with built-in APIs, authentication, and real-time sync, all
17isolated from other slices.
18
19### Why Slices Matter
20
21In the AT Protocol ecosystem, data lives on Personal Data Servers (PDS)
22scattered across the network. Slices acts as an **AppView** that:
23
24- Aggregates data from across the network
25- Applies your custom schemas
26- Provides instant APIs for your data
27- Maintains complete data isolation
28
29### Creating Your Slice
30
31When you create a slice for `com.recordcollector`:
32
33```
34Slice Name: My Vinyl Collection
35Domain: com.recordcollector
36URI: at://did:plc:abc123/network.slices.slice/xyz789
37```
38
39This slice becomes the container for all your vinyl collection data, completely
40isolated from other slices.
41
42### Key Properties
43
44- **URI**: Unique AT Protocol identifier
45- **Domain**: Your namespace (e.g., `com.recordcollector`)
46- **Isolation**: Complete data separation between slices
47- **Multi-tenancy**: Multiple users can have data in the same slice
48
49### Example: Record Collector Slice
50
51```json
52{
53 "uri": "at://did:plc:abc123/network.slices.slice/xyz789",
54 "name": "Vinyl Collection Manager",
55 "domain": "com.recordcollector",
56 "createdAt": "2024-01-15T10:00:00Z"
57}
58```
59
60## **Lexicons**: Data Schemas
61
62### What are Lexicons?
63
64Lexicons are JSON schemas that define the structure of your data in AT Protocol.
65They're like database tables with built-in validation. In Slices, these lexicons
66automatically generate APIs for you.
67
68### Defining Your Data
69
70For a record collector app, you might define an album lexicon:
71
72```json
73{
74 "lexicon": 1,
75 "id": "com.recordcollector.album",
76 "defs": {
77 "main": {
78 "type": "record",
79 "description": "A vinyl album in the collection",
80 "record": {
81 "type": "object",
82 "required": ["title", "artist", "releaseDate"],
83 "properties": {
84 "title": {
85 "type": "string",
86 "description": "Album title"
87 },
88 "artist": {
89 "type": "string",
90 "description": "Artist or band name"
91 },
92 "releaseDate": {
93 "type": "string",
94 "format": "datetime",
95 "description": "Original release date"
96 },
97 "genre": {
98 "type": "array",
99 "items": { "type": "string" },
100 "description": "Musical genres"
101 },
102 "condition": {
103 "type": "string",
104 "enum": [
105 "Mint",
106 "Near Mint",
107 "Very Good Plus",
108 "Very Good",
109 "Good",
110 "Fair",
111 "Poor"
112 ],
113 "description": "Vinyl condition grading"
114 },
115 "notes": {
116 "type": "string",
117 "maxLength": 1000,
118 "description": "Collector's notes"
119 }
120 }
121 }
122 }
123 }
124}
125```
126
127### Primary vs External Lexicons
128
129**Primary Lexicons**: Match your slice domain:
130
131- `com.recordcollector.album`
132- `com.recordcollector.review`
133- `com.recordcollector.wishlist`
134
135**External Lexicons**: From other namespaces:
136
137- `app.bsky.actor.profile` (Bluesky profiles)
138- `sh.tangled.repo` (Tangled Repo)
139- `social.grain.photo` (Grain Photos)
140- `com.cassettecollector.tape` (Cassette Collector)
141
142### Automatic API Generation
143
144Each lexicon with `type: "record"` automatically creates endpoints. Record types
145are the only lexicons that generate CRUD APIs:
146
147```
148com.recordcollector.album (type: "record") →
149 /xrpc/com.recordcollector.album.getRecords
150 /xrpc/com.recordcollector.album.createRecord
151 /xrpc/com.recordcollector.album.updateRecord
152 /xrpc/com.recordcollector.album.deleteRecord
153```
154
155Note: Other lexicon types (like `query`, `procedure`, or `subscription`) serve
156different purposes and don't create these standard CRUD endpoints.
157
158## **Sync**: Data Flow
159
160### How Data Enters Your Slice
161
162The sync engine manages how data flows into your slice from the AT Protocol
163network.
164
165### Three Sync Strategies
166
167#### 1. Bulk Sync: Historical Import
168
169Perfect for initial data loading or periodic updates. When you're first starting
170out, you might only be syncing your own records from your PDS. But as more
171people adopt your app and write records to their own PDSs, you can sync from
172their repositories too, growing your network.
173
174Specify:
175
176- Collections to sync (e.g., `com.recordcollector.album`)
177- External collections (e.g., `app.bsky.actor.profile` for user profiles)
178- Specific repositories (DIDs) to import from
179
180#### 2. User Sync: On-Demand
181
182Automatically syncs when users log in. This is primarily for discovering and
183syncing external collections. When a new user authenticates for the first time,
184they become an actor in your slice, allowing you to discover what external
185collections they have (like Bluesky profiles or posts) and sync that data from
186their PDS.
187
188#### 3. Jetstream: Real-Time Updates
189
190Connects to the AT Protocol firehose for live updates. This tracks create,
191update, and delete events as they happen across the network.
192
193```
194Firehose Event → Filter by Collection → Validate → Store in Slice
195```
196
197### Syncing External Data
198
199Import Bluesky profiles to show who owns each album and their Bluesky avatar.
200You can sync external collections like `app.bsky.actor.profile` to enrich your
201slice with user information from the broader AT Protocol network.
202
203### Performance Features
204
205- **CID Deduplication**: Skips unchanged records
206- **Bulk Operations**: Processes thousands of records efficiently
207- **Actor Caching**: Reduces database lookups
208- **Auto-Recovery**: Handles network interruptions
209
210### Example: Syncing a Vinyl Community
211
212To sync all albums from a vinyl collecting community, you would:
213
214- List primary collections (`com.recordcollector.album`,
215 `com.recordcollector.review`)
216- Include external collections (`app.bsky.actor.profile`) to show collector
217 information
218
219## **Code Generation & XRPC Endpoints**: APIs & SDKs
220
221### Dynamic API Creation
222
223Every record-type lexicon automatically generates REST-like XRPC endpoints.
224
225### Generated Endpoints
226
227For `com.recordcollector.album`:
228
229#### List Albums
230
231```http
232POST /xrpc/com.recordcollector.album.getRecords
233{
234 "slice": "at://your-slice-uri",
235 "where": { "genre": { "contains": "jazz" } },
236 "sortBy": [{ "field": "releaseDate", "direction": "desc" }],
237 "limit": 20
238}
239```
240
241#### Add Album
242
243```http
244POST /xrpc/com.recordcollector.album.createRecord
245Authorization: Bearer YOUR_TOKEN
246{
247 "slice": "at://your-slice-uri",
248 "record": {
249 "title": "Kind of Blue",
250 "artist": "Miles Davis",
251 "releaseDate": "1959-08-17T00:00:00Z",
252 "genre": ["jazz", "modal jazz"],
253 "condition": "Very Good Plus"
254 }
255}
256```
257
258### TypeScript SDK Generation
259
260Slices generates a fully-typed TypeScript client:
261
262```typescript
263// Generated SDK with full type safety
264import { AtprotoClient } from "./generated_client.ts";
265
266const client = new AtprotoClient({
267 baseUrl: "https://api.slices.network",
268 sliceUri: "at://your-slice-uri",
269 auth: oauthClient,
270});
271
272// Fully typed operations
273const albums = await client.com.recordcollector.album.getRecords({
274 where: {
275 condition: { in: ["Mint", "Near Mint"] },
276 genre: { contains: "jazz" },
277 },
278 sortBy: [{ field: "artist", direction: "asc" }],
279 limit: 50,
280});
281
282// Type-safe record creation
283const newAlbum = await client.com.recordcollector.album.createRecord({
284 title: "Blue Train",
285 artist: "John Coltrane",
286 releaseDate: "1958-01-01T00:00:00Z",
287 genre: ["jazz", "hard bop"],
288 condition: "Near Mint",
289 notes: "Original Blue Note pressing",
290});
291```
292
293### OAuth Integration
294
295Built-in OAuth 2.0 with PKCE:
296
297- Read operations: Public by default
298- Write operations: Require authentication
299- Automatic token refresh
300- Secure session management
301
302### SDK Features
303
304- **Type Safety**: Full TypeScript types from lexicons
305- **Nested APIs**: `client.com.recordcollector.album.*`
306- **Error Handling**: Automatic retries and graceful failures
307- **Blob Support**: Handle images and media files
308
309## How It All Works Together
310
311```
3121. Create Slice → Define namespace (com.recordcollector)
313 ↓
3142. Add Lexicons → Define data structure (album, review, wishlist)
315 ↓
3163. Sync Data → Import existing vinyl collections
317 → Subscribe to real-time updates
318 ↓
3194. Use APIs → Generated endpoints for all operations
320 → Type-safe SDK for your app
321```
322
323## Practical Example: Building a Vinyl Collector App
324
325### Step 1: Create Your Slice
326
327Create a slice using the Slices CLI or web interface:
328
329- Name: "Vintage Vinyl Collectors"
330- Domain: "com.recordcollector"
331
332### Step 2: Define Lexicons
333
334Upload your lexicon definitions through the web UI or CLI:
335
336- Album schema (`com.recordcollector.album`)
337- Review schema (`com.recordcollector.review`)
338- Wishlist schema (`com.recordcollector.wishlist`)
339
340### Step 3: Sync Existing Data
341
342Start a sync job to import your existing collection:
343
344- Use the Sync tab in the web UI
345- Select collections to sync
346- Specify repositories (or leave empty for all)
347
348### Step 4: Build Your App
349
350```javascript
351// Use the generated SDK
352const client = new AtprotoClient(slice.uri);
353
354// List all jazz albums in mint condition
355const jazzMint = await client.com.recordcollector.album.getRecords({
356 where: {
357 genre: { contains: "jazz" },
358 condition: { eq: "Mint" },
359 },
360});
361
362// Add a new album to the collection
363await client.com.recordcollector.album.createRecord({
364 title: "A Love Supreme",
365 artist: "John Coltrane",
366 releaseDate: "1965-02-01T00:00:00Z",
367 genre: ["jazz", "spiritual jazz"],
368 condition: "Near Mint",
369});
370```
371
372## Summary
373
374| Concept | Purpose | Record Collector Example |
375| ------------ | ------------------------------- | ----------------------------------------------------------- |
376| **Slices** | Isolated data container | `com.recordcollector` namespace with all your vinyl data |
377| **Lexicons** | Schema definitions | `album`, `review`, `wishlist` record types |
378| **Sync** | Data import & real-time updates | Import collections from network, live updates via Jetstream |
379| **Code Gen** | Auto-generated APIs & SDKs | TypeScript client with `getRecords`, `createRecord`, etc. |
380
381## Next Steps
382
383- [Getting Started](./getting-started.md): Create your first slice
384- [API Reference](./api-reference.md): Detailed endpoint documentation
385- [SDK Usage](./sdk-usage.md): Advanced SDK patterns