Azure Logic Apps Expressions & Functions

Dynamic Workflow Logic


Introduction

Logic Apps expressions provide a powerful way to create dynamic, data-driven workflows. Expressions allow you to access and transform data, perform calculations, make decisions, and construct complex values at runtime. Understanding expressions is essential for building sophisticated integration workflows that can handle varying data formats and business conditions.

This comprehensive guide covers:

  • Expression syntax — Understanding @{} notation
  • Function categories — String, date, logical, collection operations
  • Data access — Reading from triggers and previous actions
  • Variable operations — Working with variables and arrays
  • Complex expressions — Building nested, multi-function expressions
  • Best practices — Writing efficient, maintainable expressions

Understanding Expression Syntax

Basic Expression Structure

┌─────────────────────────────────────────────────────────────────────┐
│                     EXPRESSION SYNTAX                               │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│   Simple Expression                                                 │
│   ──────────────────                                                │
│   @{triggerBody()['orderId']}                                       │
│   │                  │                                              │
│   │                  └── JSON path (orderId)                        │
│   │                                                                 │
│   └──── Expression wrapper (always use @{})                         │
│                                                                     │
│   Function Expression                                               │
│   ───────────────────                                               │
│   @{toUpper('hello world')}                                         │
│   │                    │                                            │
│   │                    └── Function parameter                       │
│   │                                                                 │
│   └────── Function name (toUpper)                                   │
│                                                                     │
│   Nested Expression                                                 │
│   ──────────────────                                                │
│   @{addDays(utcNow(), variables('daysToAdd'))}                      │
│   │        │            │           │                               │
│   │        │            │           └── Variable reference          │
│   │        │            └──── Parameter                             │
│   │        └──── Nested function call                               │
│   └──────── Outer function                                          │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

Expression Evaluation Flow

┌─────────────────────────────────────────────────────────────────────┐
│                  EXPRESSION EVALUATION FLOW                         │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│   ┌─────────────────────────────────────────────────────────────┐   │
│   │              DESIGN TIME (Logic App Editor)                 │   │
│   │                                                             │   │
│   │   "@addDays(utcNow(), 7)"                                   │   │
│   │         │                                                   │   │
│   │         ▼                                                   │   │
│   │   Validated and type-checked                                │   │
│   └────────────────────────────┬────────────────────────────────┘   │
│                                │                                    │
│                                ▼                                    │
│   ┌─────────────────────────────────────────────────────────────┐   │
│   │              RUNTIME (Workflow Execution)                   │   │
│   │                                                             │   │
│   │   1. Evaluate: utcNow() → 2024-01-15T10:30:00Z              │   │
│   │   2. Evaluate: 7 (constant) → 7                             │   │
│   │   3. Execute: addDays(result1, result2)                     │   │
│   │   4. Result: 2024-01-22T10:30:00Z                           │   │
│   └────────────────────────────┬────────────────────────────────┘   │
│                                │                                    │
│                                ▼                                    │
│   ┌─────────────────────────────────────────────────────────────┐   │
│   │              OUTPUT (Action Input)                          │   │
│   │                                                             │   │
│   │   Used as parameter in next action                          │   │
│   └─────────────────────────────────────────────────────────────┘   │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

String Functions

Common String Operations

{
  "Transform_text": {
    "type": "Compose",
    "inputs": {
      "uppercase": "@toUpper('hello world')",
      "lowercase": "@toLower('HELLO WORLD')",
      "trimmed": "@trim('  hello world  ')",
      "substring": "@substring('Hello World', 0, 5)",
      "length": "@length('Hello')",
      "concat": "@concat('Hello', ' ', 'World')",
      "replace": "@replace('Hello World', 'World', 'Universe')",
      "split": "@split('a,b,c', ',')",
      "startsWith": "@startsWith('Hello World', 'Hello')",
      "endsWith": "@endsWith('Hello World', 'World')"
    }
  }
}

String Function Reference

FunctionDescriptionExample
toUpper(text)Convert to uppercase@toUpper('hello') → "HELLO"
toLower(text)Convert to lowercase@toLower('HELLO') → "hello"
trim(text)Remove leading/trailing spaces@trim(' hello ') → "hello"
substring(text, start, length)Extract substring@substring('Hello', 0, 3) → "Hel"
length(text)Get string length@length('Hello') → 5
concat(text1, text2, ...)Concatenate strings@concat('A', 'B') → "AB"
replace(text, old, new)Replace substring@replace('Hi', 'Hi', 'Hello') → "Hello"
split(text, delimiter)Split into array@split('a,b', ',') → ["a","b"]
startsWith(text, prefix)Check prefix@startsWith('Hello', 'He') → true
endsWith(text, suffix)Check suffix@endsWith('Hello', 'lo') → true

JSON String Functions

{
  "Json_operations": {
    "type": "Compose",
    "inputs": {
      "parse": "@json('{\"name\": \"John\"}')",
      "stringify": "@string(json('{\"name\": \"John\"}'))",
      "base64_encode": "@base64('Hello')",
      "base64_decode": "@base64ToString('SGVsbG8=')"
    }
  }
}

Date and Time Functions

DateTime Operations

{
  "Date_operations": {
    "type": "Compose",
    "inputs": {
      "current_time": "@utcNow()",
      "formatted_date": "@formatDateTime(utcNow(), 'yyyy-MM-dd')",
      "formatted_datetime": "@formatDateTime(utcNow(), 'yyyy-MM-ddTHH:mm:ssZ')",
      "add_days": "@addDays(utcNow(), 7)",
      "add_hours": "@addHours(utcNow(), 2)",
      "add_minutes": "@addMinutes(utcNow(), 30)",
      "start_of_day": "@startOfDay(utcNow())",
      "end_of_day": "@endOfDay(utcNow())",
      "start_of_week": "@startOfWeek(utcNow())",
      "timestamp_to_ticks": "@ ticks(utcNow())"
    }
  }
}

Date Format Patterns

┌─────────────────────────────────────────────────────────────────────┐
│                    DATE FORMAT PATTERNS                             │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│   Pattern    Description              Example                       │
│   ────────  ──────────────            ────────                      │
│   yyyy       Year (4 digits)          2024                          │
│   MM         Month (2 digits)          01                           │
│   dd         Day (2 digits)           15                            │
│   HH         Hour (24-hour)           14                            │
│   mm         Minutes                  30                            │
│   ss         Seconds                  45                            │
│   fff        Milliseconds             123                           │
│   zzz        Timezone offset          +05:30                        │
│                                                                     │
│   Common Formats                                                    │
│   ─────────────                                                     │
│   'yyyy-MM-dd'          → "2024-01-15"                              │
│   'yyyy-MM-dd HH:mm'    → "2024-01-15 14:30"                        │
│   'yyyy-MM-ddTHH:mm:ssZ'→ "2024-01-15T14:30:45Z"                    │
│   'MMMM dd, yyyy'       → "January 15, 2024"                        │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

Timezone Conversion

{
  "Timezone_operations": {
    "type": "Compose",
    "inputs": {
      "utc_to_pst": "@convertFromUtc(utcNow(), 'Pacific Standard Time')",
      "pst_to_utc": "@convertToUtc('2024-01-15 14:30', 'Pacific Standard Time')",
      "utc_to_ist": "@convertFromUtc(utcNow(), 'India Standard Time')"
    }
  }
}

Collection Functions

Array and Object Operations

{
  "Collection_operations": {
    "type": "Compose",
    "inputs": {
      "array_length": "@length(createArray(1, 2, 3))",
      "first_item": "@first(createArray(1, 2, 3))",
      "last_item": "@last(createArray(1, 2, 3))",
      "take_items": "@take(createArray(1, 2, 3, 4, 5), 3)",
      "skip_items": "@skip(createArray(1, 2, 3, 4, 5), 2)",
      "contains": "@contains(createArray(1, 2, 3), 2)",
      "union_arrays": "@union(createArray(1, 2), createArray(2, 3))",
      "intersection": "@intersection(createArray(1, 2, 3), createArray(2, 3, 4))"
    }
  }
}

Object Property Access

{
  "Object_operations": {
    "type": "Compose",
    "inputs": {
      "object_keys": "@keys(json('{\"a\": 1, \"b\": 2}'))",
      "object_values": "@values(json('{\"a\": 1, \"b\": 2}'))",
      "coalesce": "@coalesce(null, 'default')",
      "coalesce_nested": "@coalesce(body('GetOrder')?['customerName'], variables('defaultName'))"
    }
  }
}

Filter and Map Arrays

{
  "Filter_and_map": {
    "type": "Compose",
    "inputs": {
      "filter_items": "@filter(createArray(1, 2, 3, 4, 5), (item) => greater(item, 2))",
      "map_items": "@map(createArray(1, 2, 3), (item) => mul(item, 10))"
    }
  }
}

Logical Functions

Conditionals and Comparisons

{
  "Logical_operations": {
    "type": "Compose",
    "inputs": {
      "if_then_else": "@if(equals(variables('status'), 'active'), 'Active', 'Inactive')",
      "equals": "@equals(1, 1)",
      "not_equals": "@notEquals(1, 2)",
      "greater": "@greater(10, 5)",
      "greaterOrEquals": "@greaterOrEquals(10, 10)",
      "less": "@less(5, 10)",
      "lessOrEquals": "@lessOrEquals(5, 5)",
      "and": "@and(equals(1, 1), equals(2, 2))",
      "or": "@or(equals(1, 1), equals(2, 3))",
      "not": "@not(equals(1, 2))"
    }
  }
}

Nested Conditions

{
  "Nested_condition": {
    "type": "Compose",
    "inputs": {
      "complex_if": "@if(and(greater(variables('amount'), 1000), equals(variables('priority'), 'high')), 'Priority Processing', if(greater(variables('amount'), 500), 'Standard Processing', 'Basic Processing'))"
    }
  }
}

Access Trigger Data

Trigger Body Access

{
  "Access_trigger": {
    "type": "Compose",
    "inputs": {
      "full_body": "@triggerBody()",
      "specific_field": "@triggerBody()['orderId']",
      "nested_field": "@triggerBody()['customer']['email']",
      "array_item": "@triggerBody()['items'][0]",
      "array_length": "@length(triggerBody()['items'])"
    }
  }
}

Trigger Headers and Outputs

{
  "Access_outputs": {
    "type": "Compose",
    "inputs": {
      "headers": "@triggerOutputs()['headers']",
      "statusCode": "@triggerOutputs()['statusCode']",
      "specific_header": "@triggerOutputs()['headers']['Content-Type']",
      "reasonPhrase": "@triggerOutputs()['reasonPhrase']"
    }
  }
}

HTTP Trigger Expressions

{
  "Http_trigger_expressions": {
    "type": "Compose",
    "inputs": {
      "query_param": "@trigger().queries.page",
      "path_param": "@trigger().parameters.id",
      "method": "@trigger().method",
      "uri": "@trigger().uri"
    }
  }
}

Access Action Outputs

Reference Previous Actions

{
  "Action_output_access": {
    "type": "Compose",
    "inputs": {
      "parse_result": "@body('Parse_JSON')",
      "specific_field": "@body('Parse_JSON')['orderId']",
      "action_result": "@outputs('Get_Order')",
      "status_code": "@outputs('HTTP_Request')['statusCode']",
      "headers": "@outputs('HTTP_Request')['headers']"
    }
  }
}

Handle Missing Data

{
  "Safe_data_access": {
    "type": "Compose",
    "inputs": {
      "coalesce": "@coalesce(body('Get_Order')?['customerName'], 'Unknown')",
      "conditional_access": "@if(contains(body('Get_Order'), 'customerName'), body('Get_Order')['customerName'], 'N/A')",
      "null_check": "@if(empty(body('Get_Customer')), 'Not Found', body('Get_Customer')['name'])"
    }
  }
}

Complex Expression Examples

Date Calculation Pipeline

{
  "Calculate_dates": {
    "type": "Compose",
    "inputs": {
      "today": "@utcNow()",
      "next_week": "@addDays(utcNow(), 7)",
      "next_week_formatted": "@formatDateTime(addDays(utcNow(), 7), 'yyyy-MM-dd')",
      "start_of_month": "@formatDateTime(startOfMonth(utcNow()), 'yyyy-MM-01')",
      "end_of_month": "@formatDateTime(endOfMonth(utcNow()), 'yyyy-MM-dd')",
      "relative_date": "@if(greater(dayOfWeek(utcNow()), 4), addDays(utcNow(), 14), addDays(utcNow(), 7))"
    }
  }
}

Data Transformation Pipeline

{
  "Transform_data": {
    "type": "Compose",
    "inputs": {
      "original": {
        "firstName": "john",
        "lastName": "doe",
        "email": "JOHN@EXAMPLE.COM"
      },
      "transformed": {
        "fullName": "@concat(toUpper(body('original')['firstName']), ' ', toUpper(body('original')['lastName']))",
        "normalizedEmail": "@toLower(body('original')['email'])",
        "initials": "@concat(substring(body('original')['firstName'], 0, 1), substring(body('original')['lastName'], 0, 1))"
      }
    }
  }
}

Array Processing

{
  "Process_arrays": {
    "type": "Compose",
    "inputs": {
      "items": [
        { "name": "Item1", "price": 100 },
        { "name": "Item2", "price": 250 },
        { "name": "Item3", "price": 50 }
      ],
      "total_price": "@sum(body('items')[*]['price'])",
      "expensive_items": "@filter(body('items'), (item) => greater(item['price'], 100))",
      "item_names": "@map(body('items'), (item) => item['name'])"
    }
  }
}

Use in Different Action Types

Set Variable

{
  "Set_variable": {
    "type": "SetVariable",
    "inputs": {
      "name": "orderId",
      "value": "@triggerBody()['orderId']"
    }
  }
}

Condition (If)

{
  "If_action": {
    "type": "If",
    "expression": "@greater(variables('totalAmount'), 1000)",
    "actions": {
      "Send_priority_email": { "type": "SendEmail" }
    },
    "else": {
      "Send_normal_email": { "type": "SendEmail" }
    }
  }
}

Switch

{
  "Switch_action": {
    "type": "Switch",
    "expression": "@triggerBody()['status']",
    "cases": {
      "new": {
        "actions": {
          "Handle_new": { "type": "HandleNewOrder" }
        }
      },
      "processing": {
        "actions": {
          "Handle_processing": { "type": "HandleProcessing" }
        }
      },
      "completed": {
        "actions": {
          "Handle_completed": { "type": "HandleCompleted" }
        }
      }
    }
  }
}

For Each Loop

{
  "For_each": {
    "type": "ForEach",
    "foreach": "@body('Get_Orders')['orders']",
    "actions": {
      "Process_item": {
        "type": "Compose",
        "inputs": {
          "itemName": "@item()['name']",
          "upperName": "@toUpper(item()['name'])"
        }
      }
    }
  }
}

Best Practices

Expression Design

PracticeDescription
Use coalesceHandle null/missing values safely
Test thoroughlyVerify expressions with various inputs
Keep simpleBreak complex expressions into steps
Document intentAdd comments for complex logic

Performance Considerations

{
  "Performance_tips": {
    "type": "Compose",
    "inputs": {
      "good": "@body('Get_Order')['customerId']",
      "avoid": "@if(contains(body('Get_Order'), 'customerId'), body('Get_Order')['customerId'], '')"
    }
  }
}

Debugging Expressions

{
  "Debug_compose": {
    "type": "Compose",
    "inputs": {
      "debug_value": "@variables('myVariable')",
      "trace": "@concat('Processing order: ', string(variables('orderId')))"
    }
  }
}

Related Topics


Azure Integration Hub - Intermediate Level