Expressions

A mapping expression computes one value. Corma uses expressions in two directions:

The language is the same in both directions. Only the variables differ, and the first segment of a path says which set you are in.

An expression crosses the wire as a string, exactly as it is written. Corma parses it, so the API never exposes a syntax tree. An expression can hold 4096 characters.

Corma checks an expression when you store it. A path that the direction does not offer is refused with the code invalid_expression, and no mapping is written.

Variables: reading from a connector

An inbound variable is a path, and its first segment is the connector it reads from:

google.primaryEmail
google.name.fullName
personio.attributes.department

The paths are not guessed: GET /connectors/{id}/fields lists every field a connector exposes, and the id of a field is the variable to write. A field whose origin is custom is one the workspace defined in the connector itself; it is listed once Corma has read the catalog of that connector.

A path may cross a list with [*], which yields every matching value:

google.emails[*].address

Variables: reading the Corma user

An outbound variable always starts with user:

user.email
user.jobTitle
user.managerEmail
user.customFields.matricule

The paths are not guessed here either: GET /user-fields lists every field a Corma user carries, and user. followed by the id of a field is the variable to write. A field whose origin is custom is one the workspace defined; its identifier already starts with custom., and it is read as user.customFields.<key>.

Two rules apply to this direction only:

  • Write the id of the field, not the label an interface shows: user.jobTitle, not user.job title. Every Corma user field can be read outbound, including the ones no connector may write into, such as the professional email.
  • A path that names a person — user.managerEmail, or a custom field whose type is user — must produce an email address or the identifier of the account in the connector. An expression that produces a display name resolves to nobody, and Corma writes nothing.

Functions

A function call takes arguments that are themselves values, variables or calls:

coalesce(google.name.fullName, google.name.familyName, google.primaryEmail)
if(google.suspended, "suspended", "active")
upper(trim(personio.attributes.department))

GET /expression-functions lists every function, with its arguments and the type it returns. Read that list rather than hard-coding one: functions are added over time.

Three fields of a function deserve attention:

  • params is the ordered list of arguments. The number of arguments comes from this list.
  • variadic on the last argument means it repeats. concat declares one argument and accepts any number of values.
  • values on an argument closes it over a fixed list. date_add accepts only those units, and the expression is refused if you send another. Offer them as a choice rather than free text.
  • returnType is inherit when the function gives back one of its arguments. coalesce returns whatever its arguments hold, so its result has their type.

Literals

Kind How to write it Example
Text Double quotes "active"
Number Digits 42
Boolean true or false true
Nothing null null

What an empty result means

An expression that resolves to nothing yields null. A mapping decides what happens then: by default Corma leaves the current value alone, so a connector that stops sending a field does not erase what another source wrote.

Examples

Inbound

A workspace reads its users from Google, and wants the display name to fall back twice:

coalesce(google.name.fullName, google.name.familyName, google.primaryEmail)
  • A user with a full name gets it.
  • A user with only a family name gets that.
  • A user with neither gets their email address, so the field is never empty.

Outbound

The same workspace creates Google accounts, and wants the job title to come from Corma, with the department as a fallback:

coalesce(user.jobTitle, user.teamName)

A field Corma must not write at all is not deleted — it is switched off, with {"mode": "skip"}. Deleting the mapping restores Corma's own default instead. A field the connector needs to create an account cannot be switched off, and the API refuses it with the code invalid_mapping.