Skip to content

OData Query Options

The Nymbl API supports a subset of the OData v4 query options, providing filtering, sorting, and data selection capabilities. Not all OData v4 features are implemented.

System Query Options

Query options are appended to the URL using the format ?$option=value. Multiple options can be combined using &.

$filter

Filter results based on property values.

Example: Filter by exact match

GET /Patients?$filter=last_name eq 'Smith'

Example: Filter by date range

GET /Appointments?$filter=appointment_date ge '2024-01-01' and appointment_date le '2024-12-31'

Comparison Operators

Operator Description Example
eq Equal status eq 'confirmed'
ne Not equal status ne 'cancelled'
gt Greater than age gt 18
ge Greater than or equal date ge '2024-01-01'
lt Less than age lt 65
le Less than or equal date le '2024-12-31'

Logical Operators

Operator Description Example
and Logical AND first_name eq 'John' and last_name eq 'Smith'
or Logical OR status eq 'confirmed' or status eq 'pending'
not Logical negation not (status eq 'cancelled')

String Functions

Function Description Example
contains Contains substring contains(last_name,'mit')
startswith Starts with string startswith(last_name,'Sm')
endswith Ends with string endswith(last_name,'ith')

$select

Choose specific properties to include in the response.

Example:

GET /Patients?$select=first_name,last_name,date_of_birth

Response:

{
  "value": [
    {
      "first_name": "John",
      "last_name": "Smith",
      "date_of_birth": "1980-05-15"
    }
  ]
}

$orderby

Sort results by one or more properties.

Example: Single property ascending

GET /Patients?$orderby=last_name

Example: Multiple properties

GET /Patients?$orderby=last_name,first_name

Example: Descending order

GET /Appointments?$orderby=appointment_date desc

$top and $skip

Paginate through large result sets.

Example: Get first 10 records

GET /Patients?$top=10

Example: Get records 11-20

GET /Patients?$top=10&$skip=10

Maximum page size: 100 records

$count

Include the total count of records matching the query.

Example:

GET /Patients?$count=true&$top=10

Response:

{
  "@odata.count": 523,
  "value": [
    // First 10 records
  ]
}

$expand

Include related entities in the response.

Example: Patients with their appointments

GET /Patients?$expand=Appointments

Response:

{
  "value": [
    {
      "patient_id": 12345,
      "first_name": "John",
      "last_name": "Smith",
      "appointments": [
        {
          "appointment_id": 67890,
          "appointment_date": "2024-02-20",
          "status": "confirmed"
        }
      ]
    }
  ]
}

Nested Query Options in $expand

You can use query options within $expand:

Example: Expand with filter

GET /Patients?$expand=Appointments($filter=status eq 'confirmed')

Example: Expand with select and orderby

GET /Patients?$expand=Appointments($select=appointment_date,status;$orderby=appointment_date desc)

Example: Nested expansion

GET /Patients?$expand=Appointments($expand=Physician)

Maximum expand depth: 3 levels

Lambda Expressions

Use any and all operators to filter based on related collections.

any() - At Least One Match

Example: Patients with at least one confirmed appointment

GET /Patients?$filter=Appointments/any(a: a/status eq 'confirmed')

Example: Patients with any appointment

GET /Patients?$filter=Appointments/any()

all() - All Match

Example: Patients where all appointments are confirmed

GET /Patients?$filter=Appointments/all(a: a/status eq 'confirmed')

Combining Query Options

Multiple query options can be combined to create complex queries.

Example: Complex query

GET /Patients
  ?$filter=contains(last_name,'Smith') and Appointments/any(a: a/status eq 'confirmed')
  &$expand=Appointments($filter=status eq 'confirmed';$orderby=appointment_date desc)
  &$select=first_name,last_name,date_of_birth
  &$orderby=last_name
  &$top=20
  &$count=true

This query: - Filters patients with 'Smith' in their last name who have confirmed appointments - Expands only confirmed appointments, sorted by date descending - Selects only specific patient fields - Orders results by last name - Returns first 20 results - Includes total count

URL Encoding

Remember to URL encode query parameters when making HTTP requests:

Character Encoded
$ %24
Space %20 or +
' %27
: %3A
/ %2F

Example:

# Before encoding:
/Patients?$filter=last_name eq 'Smith'

# After encoding:
/Patients?%24filter=last_name%20eq%20%27Smith%27

Most HTTP clients handle URL encoding automatically.

Query Limitations

Limit Value Reason
Page size 100 Performance
Expand depth 3 Performance
Filter complexity No hard limit Complex filters may timeout

Best Practices

Performance Tips

  • Use $select to request only needed properties
  • Prefer $top with pagination over retrieving all records
  • Use $filter server-side rather than filtering in your application
  • Limit $expand depth to what you actually need
  • Use $count=true only when you need the total count

Common Mistakes

  • Forgetting to URL encode query parameters
  • Using double quotes instead of single quotes in filters
  • Not respecting the maximum page size (100 records)
  • Excessive expand depth causing performance issues