Skip to main content

JSON Processing

JSON is a lightweight, text-based data exchange format derived from JavaScript. It is widely used in web services, APIs, microservices, and other connected applications, making it the most common data format in modern integration and API development.

WSO2 Integrator provides built-in support for JSON processing, allowing developers to easily create, read, modify, validate, and transform JSON data without relying on external libraries. This native support simplifies integration development and enables efficient handling of JSON payloads across different systems and services.

Creating JSON values

Construct JSON directly using Ballerina types. The json type accepts null, booleans, numbers, strings, arrays, and maps.

  1. Add a Variable: In the flow designer, click + and select Declare Variable. Set the type to json and enter a JSON value as the expression.

  2. Build nested structures: Add additional Declare Variable steps for nested JSON objects and arrays. Each variable appears as a separate Declare Variable step in the flow.

    Flow designer showing Declare Variable steps for JSON value construction including nested objects and arrays

  3. Configure the expression: Click a variable node to view and edit the JSON expression in the side panel.

Accessing JSON values

Access JSON fields with field access. Since json is dynamically shaped, most access operations return json and may require type narrowing.

  1. Define the JSON input: In the flow designer, click + and select Declare Variable. Set the type to json and enter the JSON value as the expression. Name the variable payload. This variable is then referenced in all subsequent field access steps.

  2. Add Variable steps for field access: Click + and select Declare Variable. Set the type to json and enter a field access expression on payload, such as check payload.orderId.

  3. Use optional access: For keys that may not exist, use ?. syntax in the expression (for example, check payload?.notes) to return () instead of an error.

  4. Narrow to a specific type: Set the variable type to string, int, or another concrete type and use check in the expression to perform type narrowing.

    Flow designer showing Declare Variable steps for JSON field access, optional access, and type narrowing

Parse a JSON string

Parse JSON payloads received as strings into either an untyped json value or a typed Ballerina record.

Into a JSON value

Use fromJsonString() when you need a quick untyped json value without defining a record type.

  1. Add a Declare Variable step for the raw string: In the flow designer, click + and select Declare Variable. Set the type to string and enter the JSON string as the expression. Name the variable raw.

  2. Parse the string: Click + and select Call Function. In the right-side panel, search for fromJsonString and select it. Pass raw as the argument and set the result type to json.

  3. Extract typed values: Add a Declare Variable step with a concrete type (for example, string) and use a field access expression such as check parsed.name to extract values from the parsed JSON.

    Flow designer showing the fromJsonString function call step and variable extraction steps

Into a typed record

Use jsondata:parseString() when the JSON structure is known. Define a matching record type and parse directly into it for compile-time type safety.

  1. Define the target record type: Navigate to Types in the sidebar and click + to add a new type. Define the Product record. For details on creating types, see Types.

    New Type panel showing the Product record fields defined from scratch

  2. Add a Declare Variable step for the JSON string: In the flow designer, click + and select Declare Variable. Set the type to string and enter the JSON string as the expression. Name the variable jsonStr.

  3. Parse into the record type: Click + and select Call Function. In the right-side panel, search for parseString and select it from the data.jsondata module.

    Right-side panel showing parseString search results with the data.jsondata module entry highlighted

    Pass jsonStr as the argument. The module is automatically imported into your file.

    Right-side panel showing the parseString function form with jsonStr as the argument and Product as the return type

    Flow designer showing the parseString function call step with Product as the result type

Convert a json value to a typed record

Use jsondata:parseAsType() when you already have a json value and want to convert it into a typed record.

  1. Define the record type: Navigate to Types in the sidebar and click + to add a new type. Define the record with the fields matching your JSON structure. For details on creating types, see Types.

  2. Assign the json value: In the flow designer, click + and select Declare Variable. Set the type to json and enter the JSON value as the expression. Name the variable jsonInput.

  3. Convert to the record type: Click + and select Call Function. In the right-side panel, search for parseAsType and select it from the data.jsondata module. Pass jsonInput as the argument and set the result type to your defined record.

    right-side panel showing parseAsType search results with the data.jsondata module entry highlighted

    Flow designer showing the parseAsType function call step with jsonInput as the argument and Product as the result type

Parse JSON arrays

Use jsondata:parseString() to parse a JSON array string directly into a typed record array. If you already have a json value instead of a string, use jsondata:parseAsType() as described in Convert a JSON value to a typed record.

  1. Define the record type: Navigate to Types in the sidebar and click + to add a new type. Define the OrderItem record from scratch with the following fields: sku (string), quantity (int), and unitPrice (decimal). For details on creating types, see Types.

  2. Add a Variable step for the JSON string: In the flow designer, click + and select Declare Variable. Set the type to string and enter the JSON array string as the expression. Name the variable itemsJson.

  3. Parse the array: Click + and select Call Function. In the right-side panel, search for parseString and select it from the data.jsondata module. Pass itemsJson as the argument and set the result type to OrderItem[].

    Flow designer showing the jsondata parseString function call step for parsing a JSON array into typed records

Merging JSON objects

Combine multiple JSON objects using the mergeJson function.

  1. Add Variable steps: In the flow designer, click + and select Declare Variable. Set the type to json and enter the JSON value as the expression. Add a second Declare Variable step for the merge.

  2. Merge the objects: Click + and select Call Function. In the right-side panel, search for mergeJson and select it from the lang.value module. Pass two json values as arguments.

    Flow designer showing two Declare Variable steps for order1 and order2 followed by a mergeJson function call step

Additional scenarios

Remap field names

Use the @jsondata:Name annotation to map JSON field names to Ballerina record fields when the JSON keys do not match Ballerina naming conventions or identifier rules. This is useful when working with external APIs that use naming styles such as snake_case or kebab-case. Add the annotation directly to the record type definition in types.bal after creating the record.

import ballerina/data.jsondata;

type ApiResponse record {|
@jsondata:Name {value: "total_count"}
int totalCount;
@jsondata:Name {value: "next_page"}
string? nextPage;
|};

Null handling

Use optional types (?) to represent fields that may be missing or contain null values. Combine them with the Elvis operator (?:) to provide default values when a field is absent or evaluates to null. This helps safely process incomplete or optional JSON data without additional null checks.

  1. Use optional access: Add a Declare Variable step with the type json? and use optional access syntax check payload?.description as the expression. This returns () for null or missing fields.

  2. Apply the Elvis operator: Add another Declare Variable step with a concrete type (for example, string) and use a conditional expression such as desc is string ? desc : "No description provided" to provide a default value.

    Flow designer showing Declare Variable steps for optional access and Elvis operator for null handling

Large JSON payloads

For large JSON payloads, use jsondata:parseStream() to process JSON data directly from a byte stream without loading the entire payload into memory. This approach improves memory efficiency and is useful when handling large API responses, files, or streaming data sources.

Flow designer showing a parseStream function call step reading a byte stream into a typed Product array

What's next