Auto-indexing service and GraphQL API for AT Protocol Records quickslice.slices.network/
atproto gleam graphql
at main 280 lines 5.2 kB view raw view rendered
1# Common Patterns 2 3Recipes for common use cases when building with Quickslice. 4 5## Profile Lookups 6 7Join author profiles to any record type to display names and avatars. 8 9```graphql 10query PostsWithAuthors { 11 myAppPost(first: 20, sortBy: [{ field: createdAt, direction: DESC }]) { 12 edges { 13 node { 14 content 15 createdAt 16 appBskyActorProfileByDid { 17 displayName 18 avatar { url(preset: "avatar") } 19 } 20 } 21 } 22 } 23} 24``` 25 26The `appBskyActorProfileByDid` field works on all records because every record has a `did` field. 27 28## User Timelines 29 30Fetch all records by a specific user using DID joins from their profile. 31 32```graphql 33query UserTimeline($handle: String!) { 34 appBskyActorProfile(first: 1, where: { actorHandle: { eq: $handle } }) { 35 edges { 36 node { 37 displayName 38 myAppPostByDid(first: 20, sortBy: [{ field: createdAt, direction: DESC }]) { 39 edges { 40 node { 41 content 42 createdAt 43 } 44 } 45 } 46 } 47 } 48 } 49} 50``` 51 52## Engagement Counts 53 54Use reverse joins with `totalCount` to show likes, comments, or other engagement metrics. 55 56```graphql 57query PhotosWithEngagement { 58 socialGrainPhoto(first: 10) { 59 edges { 60 node { 61 uri 62 alt 63 socialGrainFavoriteViaSubject { 64 totalCount 65 } 66 socialGrainCommentViaSubject { 67 totalCount 68 } 69 } 70 } 71 } 72} 73``` 74 75## Feed with Nested Data 76 77Build a rich feed by combining multiple join types. 78 79```graphql 80query Feed { 81 myAppPost(first: 20, sortBy: [{ field: createdAt, direction: DESC }]) { 82 edges { 83 node { 84 uri 85 content 86 createdAt 87 88 # Author profile 89 appBskyActorProfileByDid { 90 displayName 91 avatar { url(preset: "avatar") } 92 } 93 94 # Engagement counts 95 myAppLikeViaSubject { 96 totalCount 97 } 98 myAppCommentViaSubject { 99 totalCount 100 } 101 102 # Preview of recent comments 103 myAppCommentViaSubject(first: 3, sortBy: [{ field: createdAt, direction: DESC }]) { 104 edges { 105 node { 106 text 107 appBskyActorProfileByDid { 108 displayName 109 } 110 } 111 } 112 } 113 } 114 } 115 } 116} 117``` 118 119## Paginated Lists 120 121Implement infinite scroll or "load more" with cursor-based pagination. 122 123```graphql 124query PaginatedStatuses($cursor: String) { 125 xyzStatusphereStatus( 126 first: 20 127 after: $cursor 128 sortBy: [{ field: createdAt, direction: DESC }] 129 ) { 130 edges { 131 node { 132 status 133 createdAt 134 } 135 } 136 pageInfo { 137 hasNextPage 138 endCursor 139 } 140 } 141} 142``` 143 144First request: `{ "cursor": null }` 145 146Subsequent requests: `{ "cursor": "endCursor_from_previous_response" }` 147 148Continue until `hasNextPage` is `false`. 149 150## Filtered Search 151 152Combine multiple filters for search functionality. 153 154```graphql 155query SearchProfiles($query: String!) { 156 appBskyActorProfile( 157 first: 20 158 where: { displayName: { contains: $query } } 159 sortBy: [{ field: displayName, direction: ASC }] 160 ) { 161 edges { 162 node { 163 actorHandle 164 displayName 165 description 166 avatar { url(preset: "avatar") } 167 } 168 } 169 } 170} 171``` 172 173## Date Range Queries 174 175Filter records within a time period. 176 177```graphql 178query RecentActivity($since: DateTime!, $until: DateTime!) { 179 myAppPost( 180 where: { 181 createdAt: { gte: $since, lt: $until } 182 } 183 sortBy: [{ field: createdAt, direction: DESC }] 184 ) { 185 edges { 186 node { 187 content 188 createdAt 189 } 190 } 191 totalCount 192 } 193} 194``` 195 196Variables: 197```json 198{ 199 "since": "2025-01-01T00:00:00Z", 200 "until": "2025-02-01T00:00:00Z" 201} 202``` 203 204## Current User's Data 205 206Use the `viewer` query to get the authenticated user's records. 207 208```graphql 209query MyProfile { 210 viewer { 211 did 212 handle 213 appBskyActorProfileByDid { 214 displayName 215 description 216 avatar { url(preset: "avatar") } 217 } 218 myAppPostByDid(first: 10, sortBy: [{ field: createdAt, direction: DESC }]) { 219 totalCount 220 edges { 221 node { 222 content 223 createdAt 224 } 225 } 226 } 227 } 228} 229``` 230 231## Real-Time Updates 232 233Subscribe to new records and update your UI live. 234 235```graphql 236subscription NewStatuses { 237 xyzStatusphereStatusCreated { 238 uri 239 status 240 createdAt 241 appBskyActorProfileByDid { 242 displayName 243 avatar { url(preset: "avatar") } 244 } 245 } 246} 247``` 248 249Combine with an initial query to show existing data, then append new records as they arrive via subscription. 250 251## Aggregations 252 253Get statistics like top items or activity over time. 254 255```graphql 256query TopArtists($user: String!) { 257 fmTealAlphaFeedPlayAggregated( 258 groupBy: [{ field: artists }] 259 where: { actorHandle: { eq: $user } } 260 orderBy: { count: DESC } 261 limit: 10 262 ) { 263 artists 264 count 265 } 266} 267``` 268 269```graphql 270query MonthlyActivity($user: String!) { 271 myAppPostAggregated( 272 groupBy: [{ field: createdAt, interval: MONTH }] 273 where: { actorHandle: { eq: $user } } 274 orderBy: { count: DESC } 275 ) { 276 createdAt 277 count 278 } 279} 280```