Back to all resources
ContX IQ ContX IQ Json

ContX IQ: Check Resource Availability Using OPTIONAL MATCH and CASE Expression

Demonstrates OPTIONAL MATCH for pattern matching that doesn't fail when no match exists, combined with CASE expressions for conditional logic. Example: Check if a subdomain is available for registration.

ContX IQ: Check Resource Availability Using OPTIONAL MATCH and CASE Expression

This example demonstrates OPTIONAL MATCH with CASE expressions:

What is OPTIONAL MATCH?

Unlike regular MATCH, OPTIONAL MATCH continues query execution even when no match is found (returns null instead of failing).

What is CASE expression?

Conditional logic in Cypher that returns different values based on conditions.

Combined pattern:

OPTIONAL MATCH (tenant:Tenant)-[:HAS]->(prop {type: "subdomain", value: $subdomain})

RETURN CASE WHEN tenant IS NULL THEN true ELSE false END AS is_available

Use case: Check if a subdomain is available (not already registered).

Use case

Scenario: Before registering a new tenant subdomain, check if it's already taken.

Graph structure:

Tenant(Acme) -[HAS]-> Property(type: "subdomain", value: "acme.example.com")

Tenant(Beta) -[HAS]-> Property(type: "subdomain", value: "beta.example.com")

Query input: $subdomain = "newsite.example.com"

Query flow:

1. _Application authenticates (using $_appId auto-filter)

2. OPTIONAL MATCH searches for Tenant with matching subdomain property

3. No match found -> tenant = null

4. CASE evaluates: tenant IS NULL -> return true (available)

5. Result: {is_subdomain_available: true}

If subdomain existed:

- Input: $subdomain = "acme.example.com"

- Tenant(Acme) matched

- CASE evaluates: tenant IS NOT NULL -> return false

- Result: {is_subdomain_available: false}

Key concept: _Application as subject:

- Uses $_appId filter (auto-populated with Application's external_id)

- No user token required - service-to-service pattern

ikg

Requirements

Prerequisites:

- ServiceAccount credentials: For creating policies and queries (Bearer token)

- AppAgent credentials: For data ingestion and query execution (X-IK-ClientKey)

_Application as subject:

- $_appId is automatically populated when using Application credentials

- No user authentication needed for this pattern

Required API access:

- POST /capture/v1/nodes/ (capture Tenant and Property nodes)

- POST /configs/v1/authorization-policies (create policy)

- POST /configs/v1/knowledge-queries (create query)

- POST /contx-iq/v1/execute (run availability check)

Steps

Step 1: Ingest Tenant and Property Nodes

- Authentication: AppAgent credential (X-IK-ClientKey header)

- Action: POST Tenant nodes with subdomain Property nodes

- Result: Graph with existing subdomains registered

Step 2: Create Availability Check Policy

- Authentication: ServiceAccount credential (Bearer token)

- Action: POST policy with:

- Subject filter: $_appId (auto-populated for _Application)

- Aggregation permission for CASE expression results

- Result: Policy ID returned

Step 3: Create Availability Check Query

- Authentication: ServiceAccount credential (Bearer token)

- Action: POST query using:

- OPTIONAL MATCH to find existing subdomain (may return null)

- CASE expression to convert match/no-match to boolean

- Parameter: $subdomain for the subdomain to check

- Result: Query ID returned

Step 4: Execute Availability Check

- Authentication: AppAgent credential (X-IK-ClientKey header)

- Action: POST to /contx-iq/v1/execute with subdomain parameter

- Result: {is_subdomain_available: true/false}

Step 1

Capture the nodes needed for this use case.

POST https://eu.api.indykite.com/capture/v1/nodes/Json
{
  "nodes": [
    {
      "external_id": "tenant1",
      "is_identity": false,
      "type": "Tenant",
      "properties": [
        {
          "type": "name",
          "value": "Tenant1"
        },
        {
          "type": "subdomain",
          "value": "whocares"
        }
      ]
    },
    {
      "external_id": "tenant2",
      "is_identity": false,
      "type": "Tenant",
      "properties": [
        {
          "type": "name",
          "value": "Tenant2"
        },
        {
          "type": "subdomain",
          "value": "whatabout"
        }
      ]
    },
    {
      "external_id": "tenant3",
      "is_identity": false,
      "type": "Tenant",
      "properties": [
        {
          "type": "name",
          "value": "Tenant3"
        }
      ]
    }
  ]
}

Step 2

Create a CIQ Policy which designates the Subject node, the cypher, and the nodes allowed to be agregated.

policy.jsonJson
{
  "meta": {
    "policy_version": "1.0-ciq"
  },
  "subject": {
    "type": "_Application"
  },
  "condition": {
    "cypher": "MATCH (subject:_Application) WHERE subject.external_id = $_appId WITH subject OPTIONAL MATCH (tenant:Tenant)-[:HAS]->(subdomain:Property) WHERE subdomain.type = 'subdomain' AND subdomain.value = $subdomain WITH subject, CASE tenant WHEN tenant THEN false ELSE true END AS is_subdomain_available",
    "filter": []
  },
  "allowed_reads": {
    "nodes": [
      "subject.*",
      "tenant.*"
    ],
    "aggregate_values": [
      "is_subdomain_available"
    ]
  }
}

Request to create the CIQ Policy configuration using REST.

POST https://eu.api.indykite.com/configs/v1/authorization-policiesJson
{
  "project_id": "your_project_gid",
  "description": "description of policy",
  "display_name": "policy name",
  "name": "policy-name",
  "policy": "{\"meta\":{\"policy_version\":\"1.0-ciq\"},\"subject\":{\"type\":\"_Application\"},\"condition\":{\"cypher\":\"MATCH (subject:_Application) WHERE subject.external_id = $_appId WITH subject OPTIONAL MATCH (tenant:Tenant)-[:HAS]->(subdomain:Property) WHERE subdomain.type = 'subdomain' AND subdomain.value = $subdomain WITH subject, CASE tenant WHEN tenant THEN false ELSE true END AS is_subdomain_available\",\"filter\":[]},\"allowed_reads\":{\"nodes\":[\"subject.*\",\"tenant.*\"],\"aggregate_values\":[\"is_subdomain_available\"]}}",
  "status": "ACTIVE",
  "tags": []
}

Request to read the CIQ Policy configuration using REST.

policy_request.jsonJson
{
  "id": "your_policy_configuration_gid"
}

Step 3

Create a CIQ Query in the context of the policy to retrieve the designated properties.

knowledge_query.jsonJson
{
  "aggregate_values": [
    "is_subdomain_available"
  ]
}

Request to create a CIQ Query configuration using REST.

POST https://eu.api.indykite.com/configs/v1/knowledge-queriesJson
{
  "project_id": "your_project_gid",
  "description": "description of knowledge query",
  "display_name": "knowledge query name",
  "name": "knowledge-query-name",
  "policy_id": "your_policy_gid",
  "query": "{\"aggregate_values\":[\"is_subdomain_available\"]}",
  "status": "ACTIVE"
}

Read the CIQ Query Configuration.

GET https://eu.api.indykite.com/configs/v1/knowledge-queries/{id}Json
{
  "id": "your_knowledge_query_configuration_gid"
}

Step 4

Run a CIQ Execution to get the designated information.

POST https://eu.api.indykite.com/contx-iq/v1/executeJson
{
  "id": "knowledge_query_gid",
  "input_params": {
    "subdomain": "whocares"
  },
  "page_token": 1
}

CIQ Execution response.

response.jsonJson
{
  "data": [
    {
      "aggregate_values": {
        "is_subdomain_available": false
      }
    }
  ]
}