curl --request GET \
--url https://api.example.com/{collection} \
--header 'Authorization: <authorization>'{
"data": [
{
"_id": "<string>",
"...": "<any>"
}
],
"pagination": {
"cursor": "<string>",
"has_more": true,
"total": 123
}
}Query and list documents with filtering, pagination, sorting, and field projection
curl --request GET \
--url https://api.example.com/{collection} \
--header 'Authorization: <authorization>'{
"data": [
{
"_id": "<string>",
"...": "<any>"
}
],
"pagination": {
"cursor": "<string>",
"has_more": true,
"total": 123
}
}Documentation Index
Fetch the complete documentation index at: https://mintlify.com/KTS-o7/permission-mongo/llms.txt
Use this file to discover all available pages before exploring further.
max_result_size (default 10000)- for descending order.Examples:created_at - Sort by created_at ascending-created_at - Sort by created_at descendingstatus,-created_at - Sort by status ascending, then created_at descending_id is always included.Example: name,email,created_at?status=active?age={"$gt":18}?status=active&role=admincurl -X GET "https://api.example.com/users?_limit=10" \
-H "Authorization: Bearer YOUR_TOKEN"
curl -X GET "https://api.example.com/users?status=active&role=admin" \
-H "Authorization: Bearer YOUR_TOKEN"
curl -X GET "https://api.example.com/users?_sort=-created_at&_limit=20" \
-H "Authorization: Bearer YOUR_TOKEN"
curl -X GET "https://api.example.com/users?_fields=name,email,role" \
-H "Authorization: Bearer YOUR_TOKEN"
curl -X GET "https://api.example.com/users?_cursor=eyJfaWQiOiI1MDdmMWY3N2JjZjg2Y2Q3OTk0MzkwMTEifQ&_limit=20" \
-H "Authorization: Bearer YOUR_TOKEN"
curl -X GET "https://api.example.com/users?age=%7B%22%24gt%22%3A18%7D&status=active" \
-H "Authorization: Bearer YOUR_TOKEN"
{
"data": [
{
"_id": "507f1f77bcf86cd799439011",
"name": "John Doe",
"email": "john@example.com",
"role": "admin",
"status": "active",
"created_at": "2024-03-15T10:30:00Z"
},
{
"_id": "507f1f77bcf86cd799439012",
"name": "Jane Smith",
"email": "jane@example.com",
"role": "member",
"status": "active",
"created_at": "2024-03-14T09:20:00Z"
}
],
"pagination": {
"cursor": "eyJfaWQiOiI1MDdmMWY3N2JjZjg2Y2Q3OTk0MzkwMTIifQ",
"has_more": true,
"total": 157
}
}
find operation with cursor-based pagination:
// Build combined filter from user query + RBAC permissions
combinedFilter := bson.M{
"$and": []bson.M{userFilter, rbacFilter},
}
// Apply cursor for pagination
if cursor != "" {
cursorFilter := buildCursorFilter(cursorData, sortFields)
combinedFilter = combineFilters(combinedFilter, cursorFilter)
}
// Execute query with limit+1 to detect hasMore
options := options.Find().
SetLimit(int64(limit + 1)).
SetSort(buildSort(sortFields)).
SetProjection(buildProjection(fields))
cursor, err := collection.Find(ctx, combinedFilter, options)
// Cursor contains the last document's sort values
type CursorData struct {
ID string `json:"_id"`
SortValues map[string]interface{} `json:"sort_values,omitempty"`
}
// Encode cursor from last document
func EncodeCursor(lastDoc map[string]interface{}, sortFields []string) string {
cursor := CursorData{
ID: lastDoc["_id"],
SortValues: make(map[string]interface{}),
}
for _, field := range sortFields {
fieldName := strings.TrimPrefix(field, "-")
if val, ok := lastDoc[fieldName]; ok {
cursor.SortValues[fieldName] = val
}
}
data, _ := json.Marshal(cursor)
return base64.URLEncoding.EncodeToString(data)
}
// Get RBAC filter based on user's roles and collection policies
rbacFilter, err := h.rbac.GetQueryFilter(authCtx, collection, ActionRead)
// Example RBAC filters:
// - Tenant isolation: {"company_id": user.tenant_id}
// - Owner-only: {"created_by": user.id}
// - Department access: {"department": {"$in": user.departments}}
// - Hierarchical: {"owner_id": {"$in": user.subordinates}}
if len(fields) > 0 {
projection := make(bson.M)
for _, field := range fields {
projection[field] = 1
}
projection["_id"] = 1 // Always include _id for cursor
findOpts.Projection = projection
}
{
"error": "Invalid cursor"
}
{
"error": "Authentication required"
}
{
"error": "You don't have permission to perform this action",
"code": "forbidden",
"details": {
"action": "read",
"collection": "users"
}
}
{
"error": "Collection not found",
"code": "collection_not_found",
"details": {
"collection": "invalid_collection"
}
}
{
"error": "Failed to query documents",
"code": "internal_error",
"details": {
"error": "database timeout"
}
}
// Example: Index for sorting by status and created_at
db.users.createIndex({ status: 1, created_at: -1 })
total count is only computed on the first page (when no cursor is provided) because:
max_result_size)