|
| 1 | +--- |
| 2 | +title: JMESPath Functions |
| 3 | +description: Utility |
| 4 | +--- |
| 5 | + |
| 6 | +???+ tip |
| 7 | + JMESPath is a query language for JSON used by tools like the AWS CLI and Powertools for AWS Lambda (TypeScript). |
| 8 | + |
| 9 | +Built-in [JMESPath](https://jmespath.org/){target="_blank" rel="nofollow"} Functions to easily deserialize common encoded JSON payloads in Lambda functions. |
| 10 | + |
| 11 | +## Key features |
| 12 | + |
| 13 | +* Deserialize JSON from JSON strings, base64, and compressed data |
| 14 | +* Use JMESPath to extract and combine data recursively |
| 15 | +* Provides commonly used JMESPath expression with popular event sources |
| 16 | + |
| 17 | +## Getting started |
| 18 | + |
| 19 | +You might have events that contains encoded JSON payloads as string, base64, or even in compressed format. It is a common use case to decode and extract them partially or fully as part of your Lambda function invocation. |
| 20 | + |
| 21 | +Powertools for AWS Lambda (TypeScript) also have utilities like [idempotency](idempotency.md){target="_blank"} where you might need to extract a portion of your data before using them. |
| 22 | + |
| 23 | +???+ info "Terminology" |
| 24 | + **Envelope** is the terminology we use for the **JMESPath expression** to extract your JSON object from your data input. We might use those two terms interchangeably. |
| 25 | + |
| 26 | +### Extracting data |
| 27 | + |
| 28 | +You can use the `extractDataFromEnvelope` function with any [JMESPath expression](https://jmespath.org/tutorial.html){target="_blank" rel="nofollow"}. |
| 29 | + |
| 30 | +???+ tip |
| 31 | + Another common use case is to fetch deeply nested data, filter, flatten, and more. |
| 32 | + |
| 33 | +=== "extractDataFromBuiltinEnvelope.ts" |
| 34 | + ```typescript hl_lines="1 13 20" |
| 35 | + --8<-- "docs/snippets/jmespath/extractDataFromEnvelope.ts" |
| 36 | + ``` |
| 37 | + |
| 38 | +=== "extractDataFromEnvelope.json" |
| 39 | + |
| 40 | + ```json |
| 41 | + --8<-- "docs/snippets/jmespath/extractDataFromEnvelope.json" |
| 42 | + ``` |
| 43 | + |
| 44 | +### Built-in envelopes |
| 45 | + |
| 46 | +We provide built-in envelopes for popular AWS Lambda event sources to easily decode and/or deserialize JSON objects. |
| 47 | + |
| 48 | +=== "extractDataFromBuiltinEnvelope.ts" |
| 49 | + ```typescript hl_lines="2-3 15" |
| 50 | + --8<-- "docs/snippets/jmespath/extractDataFromBuiltinEnvelope.ts" |
| 51 | + ``` |
| 52 | + |
| 53 | +=== "extractDataFromBuiltinEnvelope.json" |
| 54 | + |
| 55 | + ```json hl_lines="6 15" |
| 56 | + --8<-- "docs/snippets/jmespath/extractDataFromBuiltinEnvelope.json" |
| 57 | + ``` |
| 58 | + |
| 59 | +These are all built-in envelopes you can use along with their expression as a reference: |
| 60 | + |
| 61 | +| Envelope | JMESPath expression | |
| 62 | +| --------------------------------- | ----------------------------------------------------------------------------------------- | |
| 63 | +| **`API_GATEWAY_HTTP`** | `powertools_json(body)` | |
| 64 | +| **`API_GATEWAY_REST`** | `powertools_json(body)` | |
| 65 | +| **`CLOUDWATCH_EVENTS_SCHEDULED`** | `detail` | |
| 66 | +| **`CLOUDWATCH_LOGS`** | `awslogs.powertools_base64_gzip(data) | powertools_json(@).logEvents[*]` | |
| 67 | +| **`EVENTBRIDGE`** | `detail` | |
| 68 | +| **`KINESIS_DATA_STREAM`** | `Records[*].kinesis.powertools_json(powertools_base64(data))` | |
| 69 | +| **`S3_EVENTBRIDGE_SQS`** | `Records[*].powertools_json(body).detail` | |
| 70 | +| **`S3_KINESIS_FIREHOSE`** | `records[*].powertools_json(powertools_base64(data)).Records[0]` | |
| 71 | +| **`S3_SNS_KINESIS_FIREHOSE`** | `records[*].powertools_json(powertools_base64(data)).powertools_json(Message).Records[0]` | |
| 72 | +| **`S3_SNS_SQS`** | `Records[*].powertools_json(body).powertools_json(Message).Records[0]` | |
| 73 | +| **`S3_SQS`** | `Records[*].powertools_json(body).Records[0]` | |
| 74 | +| **`SNS`** | `Records[0].Sns.Message | powertools_json(@)` | |
| 75 | +| **`SQS`** | `Records[*].powertools_json(body)` | |
| 76 | + |
| 77 | +???+ tip "Using SNS?" |
| 78 | + If you don't require SNS metadata, enable [raw message delivery](https://docs.aws.amazon.com/sns/latest/dg/sns-large-payload-raw-message-delivery.html). It will reduce multiple payload layers and size, when using SNS in combination with other services (_e.g., SQS, S3, etc_). |
| 79 | + |
| 80 | +## Advanced |
| 81 | + |
| 82 | +### Built-in JMESPath functions |
| 83 | + |
| 84 | +You can use our built-in JMESPath functions within your envelope expression. They handle deserialization for common data formats found in AWS Lambda event sources such as JSON strings, base64, and uncompress gzip data. |
| 85 | + |
| 86 | +#### powertools_json function |
| 87 | + |
| 88 | +Use `powertools_json` function to decode any JSON string anywhere a JMESPath expression is allowed. |
| 89 | + |
| 90 | +> **Idempotency scenario** |
| 91 | +
|
| 92 | +This sample will deserialize the JSON string within the `body` key before [Idempotency](./idempotency.md){target="_blank"} processes it. |
| 93 | + |
| 94 | +=== "powertools_json_idempotency_jmespath.py" |
| 95 | + |
| 96 | + ```python hl_lines="16" |
| 97 | + --8<-- "examples/jmespath_functions/src/powertools_json_idempotency_jmespath.py" |
| 98 | + ``` |
| 99 | + |
| 100 | +=== "powertools_json_idempotency_jmespath.json" |
| 101 | + |
| 102 | + ```json hl_lines="28" |
| 103 | + --8<-- "examples/jmespath_functions/src/powertools_json_idempotency_jmespath.json" |
| 104 | + ``` |
| 105 | + |
| 106 | +#### powertools_base64 function |
| 107 | + |
| 108 | +Use `powertools_base64` function to decode any base64 data. |
| 109 | + |
| 110 | +This sample will decode the base64 value within the `data` key, and deserialize the JSON string before processing. |
| 111 | + |
| 112 | +=== "powertools_base64_jmespath_function.py" |
| 113 | + |
| 114 | + ```python hl_lines="7 10 37 49 53 55 57" |
| 115 | + --8<-- "examples/jmespath_functions/src/powertools_base64_jmespath_function.py" |
| 116 | + ``` |
| 117 | + |
| 118 | +=== "powertools_base64_jmespath_schema.py" |
| 119 | + |
| 120 | + ```python hl_lines="7 8 10 12 17 19 24 26 31 33 38 40" |
| 121 | + --8<-- "examples/jmespath_functions/src/powertools_base64_jmespath_schema.py" |
| 122 | + ``` |
| 123 | + |
| 124 | +=== "powertools_base64_jmespath_payload.json" |
| 125 | + |
| 126 | + ```json |
| 127 | + --8<-- "examples/jmespath_functions/src/powertools_base64_jmespath_payload.json" |
| 128 | + ``` |
| 129 | + |
| 130 | +#### powertools_base64_gzip function |
| 131 | + |
| 132 | +Use `powertools_base64_gzip` function to decompress and decode base64 data. |
| 133 | + |
| 134 | +This sample will decompress and decode base64 data from Cloudwatch Logs, then use JMESPath pipeline expression to pass the result for decoding its JSON string. |
| 135 | + |
| 136 | +=== "powertools_base64_gzip_jmespath_function.py" |
| 137 | + |
| 138 | + ```python hl_lines="6 10 15 29 31 33 35" |
| 139 | + --8<-- "examples/jmespath_functions/src/powertools_base64_gzip_jmespath_function.py" |
| 140 | + ``` |
| 141 | + |
| 142 | +=== "powertools_base64_gzip_jmespath_schema.py" |
| 143 | + |
| 144 | + ```python hl_lines="7-15 17 19 24 26 31 33 38 40" |
| 145 | + --8<-- "examples/jmespath_functions/src/powertools_base64_gzip_jmespath_schema.py" |
| 146 | + ``` |
| 147 | + |
| 148 | +=== "powertools_base64_gzip_jmespath_payload.json" |
| 149 | + |
| 150 | + ```json |
| 151 | + --8<-- "examples/jmespath_functions/src/powertools_base64_gzip_jmespath_payload.json" |
| 152 | + ``` |
| 153 | + |
| 154 | +### Bring your own JMESPath function |
| 155 | + |
| 156 | +???+ warning |
| 157 | + This should only be used for advanced use cases where you have special formats not covered by the built-in functions. |
| 158 | + |
| 159 | +For special binary formats that you want to decode before processing, you can bring your own [JMESPath function](https://github.com/jmespath/jmespath.py#custom-functions){target="_blank" rel="nofollow"} and any additional option via `jmespath_options` param. To keep Powertools for AWS Lambda (TypeScript) built-in functions, you can extend the `PowertoolsFunctions` class. |
| 160 | + |
| 161 | +Here is an example of how to decompress messages using [zlib](https://docs.python.org/3/library/zlib.html){target="_blank" rel="nofollow"}: |
| 162 | + |
| 163 | +=== "powertools_custom_jmespath_function.py" |
| 164 | + |
| 165 | + ```python hl_lines="9 14 17-18 23 34 39 41 43" |
| 166 | + --8<-- "examples/jmespath_functions/src/powertools_custom_jmespath_function.py" |
| 167 | + ``` |
| 168 | + |
| 169 | +=== "powertools_custom_jmespath_function.json" |
| 170 | + |
| 171 | + ```json |
| 172 | + --8<-- "examples/jmespath_functions/src/powertools_custom_jmespath_function.json" |
| 173 | + ``` |
0 commit comments