Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stringify JSON objects #602

Open
aleksander-dytko opened this issue Mar 10, 2023 · 11 comments
Open

Stringify JSON objects #602

aleksander-dytko opened this issue Mar 10, 2023 · 11 comments
Labels
scope: Camunda 8 Required in the context of Camunda 8 type: enhancement

Comments

@aleksander-dytko
Copy link

aleksander-dytko commented Mar 10, 2023

Is your feature request related to a problem? Please describe.
During a conversation with a customer, they mentioned that it would be great to be able to structuralize JSON object with FEEL expression to stringify it.

Describe the solution you'd like
A new built-in function to return a JSON string of a FEEL value, like JSON.stringify().

// Function signature
to json(value: Any): String

// Examples
// 1) FEEL context to JSON object
to json({a: 1, b: 2})
// "{\"a\": 1, \"b\": 2}"

// 2) FEEL value to JSON literal
to json(1)
// "1"

to json("a")
// "\"a\""

to json(true)
// "true"

to json(null)
// "null"

// 3) FEEL list to JSON array
to json([1, 2, 3])
// "[1, 2, 3]"

// 4) FEEL date/time/date-time to JSON string
to json(@"2023-06-14")
// "\"2023-06-14\"" 

to json(@"14:55:00")
// "\"14:55:00\"" 

to json(@"2023-06-14T14:55:00")
// "\"2023-06-14T14:55:00\"" 

// 5) FEEL duration to JSON string 
to json(@"P1Y")
// "\"P1Y\"" 

to json(@"PT2H")
// "\"PT2H\"" 

// 6) FEEL function to JSON string 
to json(function (a, b) a + b)
// "\"<function>\"" 

// 7) FEEL range to JSON string 
to json([1..10])
// "\"[1..10]\"" 

Related issues

EDIT: I updated the description to focus on producing a JSON string and to propose a new built-in function with examples.

@saig0
Copy link
Member

saig0 commented Mar 15, 2023

@aleksander-dytko please provide more input for this issue.

What is the actual use case?
Do you have an example?
In which context is the expression evaluated? BPMN@Zeebe?

What should the function do?

In Zeebe, all variables are stored as JSON objects. In FEEL, we can access these JSON objects naturally as FEEL context objects.

The result of a FEEL expression is always a FEEL type, for example, a FEEL context.

@saig0 saig0 removed their assignment Mar 29, 2023
@vobu
Copy link

vobu commented Apr 3, 2023

@aleksander-dytko please provide more input for this issue.

What is the actual use case? Do you have an example? In which context is the expression evaluated? BPMN@Zeebe?

What should the function do?

given I talked to @aleksander-dytko about this, I should chime in here: in a BPMN task, we needed to convert a string into an object to subsequently access its' properties. This all in FEEL.

task1: job worker executes and produces a stringified representation of a JSON object (foo = '{ some:"value" }' that is sent back to the task1 and thus available in the "global" variable scope

task2: gets foo, and wants to access foo.some → prerequisite for this would be to have a way to convert the stringified JSON object into an actual runtime object. In JS, this is provided by the JSON class.
So we'd do const anotherFoo = JSON.parse(foo) to be able to subsequently do anotherFoo.some.
And to have an equivalent in FEEL would be excellent.

@saig0 saig0 self-assigned this Apr 4, 2023
@McAlm
Copy link

McAlm commented Apr 24, 2023

@aleksander-dytko: Another use case would be if a JSON string (coming from some database) is being passed to a DMN decision, e.g.

    {
        "WRAPPER": [
          {
            "jsonPayLoadAsString": "\"questions\": [{ \"type\": \"someType\" },{ \"role\": \"VN\" },{\"comment\": \"some comments\"}]\"",
            "marker": "N"
          }
        ]
    }

We are interested to evaluate some DMN rules on the jsonPayloadAsString values, so we need to transform it into a JSON object first.

@saig0
Copy link
Member

saig0 commented Apr 25, 2023

@vobu / @McAlm Thank you for providing your input. 👍

It seems that we need a new built-in function to parse a stringified JSON into a FEEL context/value.

Do we need the parsing only for JSON documents (i.e. "{..}")? Or, any kind of JSON value (i.e. "sting", 1, true)?


Note that this is different from the original requirement:

it would be great to be able to structuralize JSON object with FEEL expression to stringify it.

@saig0 saig0 removed their assignment Apr 25, 2023
@vincentgiraud
Copy link
Contributor

vincentgiraud commented May 25, 2023

Hi, I also have a use case wher I'm calling the OpenAI REST API and ask to return a proper JSON string as a response. Then I need to turn that into a FEEL context. I think a new built-in FEEL function would be good.
I also created a forum entry on this : https://forum.camunda.io/t/parse-a-json-string-to-feel-context/44755

@saig0 saig0 self-assigned this Jun 1, 2023
@saig0
Copy link
Member

saig0 commented Jun 14, 2023

@saig0
Copy link
Member

saig0 commented Jun 14, 2023

Based on the previous comments, I suggest the following new built-in functions:

Signature

Parses a string into a FEEL value:

from json(json: string): Any

Serializes a FEEL value into a JSON string:

to json(value: Any): String

Examples

// 1) JSON object to FEEL context
from json("{\"a\": 1, \"b\": 2}")
// {a: 1, b: 2}

// 2) JSON literal to FEEL value
from json("1")
// 1

from json("\"a\"")
// "a"

from json("true")
// true

from json("null")
// null

// 3) JSON array to FEEL list
from json("[1, 2, 3]")
// [1, 2, 3]

// 4) JSON string of a date/time/date-time to FEEL string 
from json("\"2023-06-14\"")
// "2023-06-14" 

from json("\"14:55:00\"")
// "14:55:00" 

from json("\"2023-06-14T14:55:00\"")
// "2023-06-14T14:55:00" 

// 5) JSON string of a duration to FEEL string 
from json("\"P1Y\"")
// "P1Y" 

from json("\"PT2H\"")
// "PT2H" 

// 6) invalid JSON to FEEL null 
from json("invalid")
// null 
// 1) FEEL context to JSON object
to json({a: 1, b: 2})
// "{\"a\": 1, \"b\": 2}"

// 2) FEEL value to JSON literal
to json(1)
// "1"

to json("a")
// "\"a\""

to json(true)
// "true"

to json(null)
// "null"

// 3) FEEL list to JSON array
to json([1, 2, 3])
// "[1, 2, 3]"

// 4) FEEL date/time/date-time to JSON string
to json(@"2023-06-14")
// "\"2023-06-14\"" 

to json(@"14:55:00")
// "\"14:55:00\"" 

to json(@"2023-06-14T14:55:00")
// "\"2023-06-14T14:55:00\"" 

// 5) FEEL duration to JSON string 
to json(@"P1Y")
// "\"P1Y\"" 

to json(@"PT2H")
// "\"PT2H\"" 

// 6) FEEL function to JSON string 
to json(function (a, b) a + b)
// "\"<function>\"" 

// 7) FEEL range to JSON string 
to json([1..10])
// "\"[1..10]\"" 

In the OMG issue, there is an interesting comment about time/date and time values with a timezone id:

[A FEEL date/time/date and time returns as] A string representation conforming to an ISO 8601 Date, Time or Date and Time combination.
If the FEEL date and time contains an IANA timezone id, the ISO 8601 Date and Time is suffixed by the IANA timezone id in rectangular brackets,
e.g. 2007-12-03T10:15:30+01:00[Europe/Paris]


@vobu / @McAlm / @vincentgiraud would this suggestion work for you?

@saig0 saig0 removed their assignment Jun 14, 2023
@vincentgiraud
Copy link
Contributor

Hi @saig0 , that would work indeed. Thanks.

@korthout
Copy link
Member

korthout commented Sep 20, 2023

@saig0 Have you considered using the string(from) conversion function for this? Currently, it returns null for any context.

@saig0
Copy link
Member

saig0 commented Sep 21, 2023

Have you considered using the string(from) conversion function for this?

@korthout good hint. But, I think that the string() function is not sufficient to produce a correct JSON representation in all cases, for example, for context and temporal types.

In this TCK test case, a context is returned as "{a: \"foo\"}" vs. "{\"a\": \"foo\"}".

Currently, it returns null for any context.

Yes. There is an open issue here: #650

I fixed this issue in the version 1.17.0.

@saig0 saig0 added the scope: Camunda 8 Required in the context of Camunda 8 label Apr 18, 2024
@saig0
Copy link
Member

saig0 commented Apr 18, 2024

I updated the issue description to focus on producing a JSON string of a FEEL value. I moved the parsing part into the issue #825.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
scope: Camunda 8 Required in the context of Camunda 8 type: enhancement
Projects
None yet
Development

No branches or pull requests

6 participants