Interface Functions

All functions are defined with camelCase name starting from lower case letter.

Functions may have parameters and may have result variables. Additionally, functions may throw expected exceptions.

Parameters

Parameters are defined as a map of name -> definition pairs. All parameters must be named in snake_case.

Parameters may have default values. A special value null marks optional parameters - it skips type checks.

{
    "funcs" : {
        "noParams" : {},
        
        "simpleParams" : {
            "params" : {
                "int_arg" : "integer",
                "str_arg" : "string",
                "custom_arg" : "MyType"
            }
        },
        
        "defaultParams" : {
            "result" : {
                "int" : {
                    "type" : "integer",
                    "default" : 1
                }
                "def_str" : {
                    "type" : "string",
                    "default" : "Some value"
                }
                "default_custom" :
                    "type" : "MyType",
                    "default" : {
                        "a" : 1,
                        "b" : "s"
                        "c" : [ 1, 2, 3 ]
                    }
                },
                "some_optional_arg": {
                    "type" : "OtherType",
                    "default" : null
                }
            }
        }
    }
}

Result

Result can be defined as a single type or a map of result variables. The later is preferred as it allows backward compatible extension of result.

All result variables must be named in snake_case. Single type has unnamed result.

{
    "funcs" : {
        "noResult" : {},
        
        "singleResult" : {
            "result" : "integer"
        },
        
        "standardResult" : {
            "result" : {
                "int_res" : "integer",
                "str_res" : "string",
                "custom_res" : "MyType"
            }
        }
    }
}

If no result variables are defined then Invoker can continue processing without waiting for response. Executor may not send any response in such case.

forcersp field can be used to force response message unconditionally. It’s applicable for light Invokers which do not process interface specification.

Exceptions

Exception is just an associative error code as defined in AsyncSteps concept.

Each function may have list of expected exceptions - generated by business process flow.

All not expected exceptions are converted to InternalError. That’s done by intention to avoid leaking sensitive information.

Errors must be defined in CamelCase starting from upper case.

{
    "funcs" : {
        "withSomeError" : {
            "throws" : [
                "MyCustomError",
                "AnotherError"
            ]
        },
    }
}

Payload size limits

Message payload size is an important security feature. The default payload limit is 64K, but it can be altered.

Note: please avoid setting too large request payload sizes as it may lead to easy Denial of Service attacks.

Payload size limit is set with maxreqsize and maxrspsize in bytes, kilobytes or megabytes with corresponding mandatory suffixes B, K or M.

{
    "funcs" : {
        "oneMegabyteRequest" : {
            "maxreqsize" : "1M"
        },
        "oneMegabyteResponse" : {
            "maxrspsize" : "1M"
        },
        "defaultLimits" : {
            "maxreqsize" : "64K",
            "maxrspsize" : "64K"
        }
    }
}

Raw request and/or response

For certain communication channels like HTTP, it’s possible to receive raw input data and/or reply with raw data. The benefit is that size of such data is limited only by channel restrictions.

Executor must never try to buffer whole raw data. Instead it should provide internal stream-like API for Service logic. Invoker should also support stream-like API for calls.

It IS possible to mix rawupload with parameters passed in HTTP query. However, it IS NOT possible to mix rawresult and result variables.

{
    "funcs" : {
        "rawUpload" : {
            "rawupload" : true,
            "params" : {
                "some_arg" : "SomeType"
            },
            "result" : {
                "some_var" : "SomeType"
            }
        },
        "rawResult" : {
            "params" : {
                "some_arg" : "SomeType"
            },
            "rawresult" : true
        },
        "rawRequestAndResponse" : {
            "rawupload" : true,
            "rawresult" : true
        }
    }
}

Heavy indicator

Executor should be able to separate “heavy” requests from ordinary fast to execute requests to avoid easy DoS attacks. There should be limit of concurrent heavy request processing with dedicated queue. Also, heavy requests may take much more time to execute.

{
    "funcs" : {
        "heavyRequest" : {
            "heavy" : true
        }
    }
}

Backward compatibility rules

  1. Parameter types:

    • type can be changed to a wider one and/or type variant,
    • all allowed input values for the older specifications must be allowed in the new specification,
    • newer specification may allow values that do not comply with older spec,
    • additional parameters can be added, but they must have default value.
  2. Result variable types must not change:

    • if single result is used then it can be changed only to 100% compatible type (e.g. alias),
    • otherwise, additional result variables can be added,
    • Invoker must expect unknown result variables,
    • new result variables must not alter result semantics.
  3. Additional functions can be added.
  4. There is no restriction for types, but they must be compatible based on parameter and result value requirements.
  5. Expected exceptions and constraints can be added or removed.