Skip to Content
DevelopmentBackendOData Query Guide

OData Query Guide

This guide covers how to use OData queries with the Rhesis backend API. All examples in this guide have been tested and verified to work with the current implementation.

Table of Contents

  1. Basic Concepts
  2. Comparison Operators
  3. String Functions
  4. Navigation Properties
  5. Logical Operators
  6. Advanced Features
  7. Complete Examples
  8. Best Practices

Basic Concepts

OData (Open Data Protocol) is a REST-based protocol for querying and updating data. In Rhesis, you can use OData filters with the $filter query parameter.

URL Format

GET /endpoint?$filter=<odata-expression>

Authentication

All requests require a Bearer token:

curl -H "Authorization: Bearer YOUR_API_KEY" "URL"

Comparison Operators

Equality Operators

Equal (eq)

# Find tests with priority = 1 GET /tests?$filter=priority eq 1 # Find behaviors with specific name GET /behaviors?$filter=name eq 'Test Behavior'

Not Equal (ne)

# Find tests where priority is not null GET /tests?$filter=priority ne null # Find behaviors not named 'Test' GET /behaviors?$filter=name ne 'Test'

Comparison Operators

Greater Than (gt)

# Find tests with priority > 0 GET /tests?$filter=priority gt 0

Less Than (lt)

# Find tests with priority < 5 GET /tests?$filter=priority lt 5

Greater Than or Equal (ge)

# Find tests with priority >= 1 GET /tests?$filter=priority ge 1

Less Than or Equal (le)

# Find tests with priority <= 5 GET /tests?$filter=priority le 5

String Functions

All string functions use function-style syntax: function(field, value)

Contains

# Find behaviors containing 'Test' in name GET /behaviors?$filter=contains(name,'Test') # Case-insensitive search GET /behaviors?$filter=contains(tolower(name),'test')

Starts With

# Find behaviors starting with 'Test' GET /behaviors?$filter=startswith(name,'Test')

Ends With

# Find behaviors ending with 'Behavior' GET /behaviors?$filter=endswith(name,'Behavior')

Case Conversion

To Lower Case (tolower)

# Case-insensitive search using tolower GET /behaviors?$filter=contains(tolower(name),'test')

To Upper Case (toupper)

# Case-insensitive search using toupper GET /behaviors?$filter=contains(toupper(name),'TEST')

Navigate through relationships using the / operator: relationship/field

Behavior Navigation

# Find tests by behavior name GET /tests?$filter=behavior/name eq 'Test Behavior' # Case-insensitive behavior search GET /tests?$filter=contains(tolower(behavior/name),'rel')

Status Navigation

# Find tests by status GET /tests?$filter=status/name eq 'New' # Find active behaviors GET /behaviors?$filter=status/name eq 'Active'

Prompt Navigation

# Find tests by prompt content GET /tests?$filter=contains(prompt/content,'test')

Topic Navigation

# Find tests by topic GET /tests?$filter=topic/name eq 'Security'

Category Navigation

# Find tests by category GET /tests?$filter=category/name eq 'Performance'

Logical Operators

AND Operator

# Multiple conditions must be true GET /tests?$filter=status/name eq 'New' and priority ne null

OR Operator

# Either condition can be true GET /tests?$filter=priority eq 1 or priority eq 2

NOT Operator

# Negate a condition (use parentheses) GET /tests?$filter=not (priority eq 1)

Complex Expressions with Parentheses

# Group conditions with parentheses GET /tests?$filter=(status/name eq 'New' and priority ne null) or contains(prompt/content,'test')

Advanced Features

Sorting

Use sort_by and sort_order parameters:

# Sort by creation date, newest first GET /tests?sort_by=created_at&sort_order=desc # Sort by priority, lowest first GET /tests?sort_by=priority&sort_order=asc

Pagination

Use skip and limit parameters:

# Get 10 items starting from item 20 GET /tests?skip=20&limit=10 # Combine with filtering GET /tests?$filter=status/name eq 'New'&skip=0&limit=50

Combining Parameters

# Filter + Sort + Paginate GET /tests?$filter=contains(tolower(behavior/name),'rel')&sort_by=created_at&sort_order=desc&skip=0&limit=25

Complete Examples

# Find all tests where behavior name contains 'rel' (case-insensitive) GET /tests?$filter=contains(tolower(behavior/name),'rel')

Example 2: Complex Multi-Condition Filter

# Find tests that are either: # - New status with non-null priority, OR # - Have 'test' in prompt content GET /tests?$filter=(status/name eq 'New' and priority ne null) or contains(prompt/content,'test')

Example 3: Advanced Search with Sorting

# Find active behaviors, sort by name GET /behaviors?$filter=status/name eq 'Active'&sort_by=name&sort_order=asc

Example 4: Navigation with String Functions

# Find tests where behavior description contains 'robust' (case-insensitive) GET /tests?$filter=contains(tolower(behavior/description),'robust')

Best Practices

1. Use Case-Insensitive Searches

For user-friendly searches, always use tolower() or toupper():

# Good: Case-insensitive GET /behaviors?$filter=contains(tolower(name),'reliability') # Avoid: Case-sensitive (user must know exact case) GET /behaviors?$filter=contains(name,'Reliability')

Instead of multiple API calls, use navigation:

# Good: Single request with navigation GET /tests?$filter=behavior/name eq 'Reliability' # Avoid: Multiple requests (less efficient) # 1. GET /behaviors?$filter=name eq 'Reliability' # 2. GET /tests?$filter=behavior_id eq 'uuid-from-step-1'

3. Use Parentheses for Complex Logic

Make complex expressions clear with parentheses:

# Good: Clear precedence GET /tests?$filter=(status/name eq 'New' or status/name eq 'Active') and priority gt 0 # Avoid: Ambiguous precedence GET /tests?$filter=status/name eq 'New' or status/name eq 'Active' and priority gt 0

4. Combine Filtering with Pagination

Always use pagination for potentially large result sets:

# Good: Paginated results GET /tests?$filter=status/name eq 'New'&limit=50 # Avoid: Potentially huge response GET /tests?$filter=status/name eq 'New'

5. URL Encoding

Remember to URL-encode your queries:

# Space becomes %20, / becomes %2F, ' becomes %27 GET /tests?%24filter=contains(behavior%2Fname,%27Test%27)

Error Handling

Common Errors

Invalid Field Names

{ "detail": "Invalid filter. Must use valid fields: field1, field2, ..." }

Parse Errors

{ "detail": "Error processing filter: Failed to parse at: Token(...)" }

Invalid Syntax Use function-style syntax for string operations:

# Correct GET /tests?$filter=contains(behavior/name,'test') # Incorrect (will cause parse error) GET /tests?$filter=behavior/name contains 'test'

Available Endpoints

The following endpoints support OData filtering:

  • /tests - Test entities
  • /behaviors - Behavior entities
  • /topics - Topic entities
  • /categories - Category entities
  • /test-sets - Test set entities
  • /test-runs - Test run entities
  • /test-results - Test result entities
  • /prompts - Prompt entities
  • /metrics - Metric entities
  • /projects - Project entities

Each endpoint supports the navigation properties defined in its model relationships.


This documentation was generated and tested on the current Rhesis backend implementation. All examples have been verified to work correctly.