spicedb icon indicating copy to clipboard operation
spicedb copied to clipboard

feat: add support for bulk resource ID filtering in ReadRelationships

Open THE-BRAHMA opened this issue 4 months ago • 4 comments

This PR introduces optional_resource_ids field to RelationshipFilter, enabling bulk relationship reads in a single API call.

After: Single bulk call

const namespaces = await spicedb.readRelationships({
  relationship_filter: {
    resource_type: "document",
    optional_resource_ids: ["DocumentA", "DocumentB", "DocumentC"],
    optional_relation: "parent"
  }
});

Implementation Details

Changes Made

  1. Validation Layer: Added counter-based mutual exclusion validation ensuring only one of optional_resource_id, optional_resource_id_prefix, or optional_resource_ids can be specified

  2. Filter Conversion: Updated RelationshipsFilterFromPublicFilter() to handle the new bulk field and convert it to internal OptionalResourceIds []string

  3. Database Optimization: Leverages existing FilterToResourceIDs() function that generates optimized IN clause queries

  4. Comprehensive Testing: Added test cases covering single IDs, multiple IDs, error scenarios, and mutual exclusion validation

Compatibility

  • Backward Compatible: Existing optional_resource_id usage unchanged
  • All Datastores: Works universally across PostgreSQL, MySQL, CockroachDB, Spanner, and MemDB
  • Validation: Prevents conflicting field usage with clear error messages

Testing

go test ./pkg/datastore -v -run TestRelationshipsFilterFromPublicFilter
go test ./internal/services/v1 -v -run TestValidateRelationshipsFilter

Related Issues

Addresses the bulk relationship reading capability discussed in https://github.com/authzed/spicedb/issues/2160

Checklist

  • [x] Implementation follows existing patterns
  • [x] Counter-based validation prevents field conflicts
  • [x] Comprehensive test coverage added
  • [x] Works across all supported datastores
  • [x] Maintains backward compatibility

THE-BRAHMA avatar Sep 05 '25 11:09 THE-BRAHMA

@THE-BRAHMA Is the intention to add support to the API layer itself as well?

josephschorr avatar Sep 05 '25 19:09 josephschorr

Yes, the API layer already supports it! No new API endpoint needed - the existing one handles both single and bulk resource IDs. Clients can now pass either a optional_resource_id or optional_resource_ids in the same RelationshipFilter Cc @josephschorr

THE-BRAHMA avatar Sep 06 '25 03:09 THE-BRAHMA

api-level support added here: https://github.com/authzed/api/pull/145

tstirrat15 avatar Sep 08 '25 19:09 tstirrat15

@josephschorr & @tstirrat15 Let me know if there is any improvement needed in this PR or is there a better way to solve this task.

THE-BRAHMA avatar Sep 12 '25 06:09 THE-BRAHMA