Working with Numbers in Requests and Reponses
LightWave exchanges messages with REST web services in JSON, or Javascript Object Notation, format. Like Javascript, JSON does not support an integer data type, only a Number type that is defined as a double-precision 64-bit binary format IEEE 754 value (number between -(253 -1) and 253 -1).
LightWave relies on schema – definitions of the structure and type of the JSON elements that make up request and responses – in order to translate data to and from structured interprocess messages that client applications can easily understand. At design-time, LightWave can automatically create request and response schemas from sample JSON requests and responses that you supply (typically documented by the owner of the web API you're working with). These schemas ultimately determine the structure of the request and response IPMs (interprocess messages) that your client application will use to invoke web APIs through LightWave at runtime. When the sample requests and responses contain numeric values, LightWave generates schema that represents the values as integer data types (including scaled integers) when possible. This behavior is based on the experience that numeric values in web APIs typically represent integral or fixed-point decimal values, not floating point values, and that COBOL programs cannot easily process floating point numbers.
For example, the consider the following JSON sample data represents a response returned from a fictional web API:
{
"price": 12345.67,
"quantity": 987,
"pi": 3.14159265358979323846264338327950288,
"avagadro": 6.02E+23
}
LightWave's 'schema by example' function generates the following schema for the sample above:
"my-sample": {
"elements": [
{
"name": "price",
"type": "int",
"scale": 2
},
{
"name": "quantity",
"type": "int"
},
{
"name": "pi",
"type": "longlong",
"scale": 15
},
{
"name": "avagadro",
"type": "double"
}
]
}
Based on the sample value of 12345.67, LightWave generates a schema type for "price" of 'scaled 32-bit signed integer' (also known as BINARY 32,2 or S9(7)V99 COMP). Based on your knowledge of the range of data that could be returned by the API, you may decide to change the type and/or scale of the schema for "price". For example, you could change it to "type": "longlong", "scale": 3 to support values with up to 15 digits to the left of the decimal and three to the right. Or, you could change type to "float" and remove "scale", indicating that you do, in fact, want to use the value as a floating point number in your application.
In the second example value, since 987 is an integral value, schema type "int" is generated. Again, you may modify the type and add "scale" if appropriate. In the third example, even though the value of pi is specified to 33 digits, Javascript truncates the value to the approximate 3.141592653589793, since this is the highest precision it can store. In this case LightWave chooses a 64-bit "longlong" with scale = 15 for the schema. The final example shows that LightWave generates a schema type of "double" for Avagradro's Number, since the value cannot be represented as a scaled integer.
You may modify the schema that LIghtWave generates based on the examples you provided. However, after doing so, you must re-export DDL definitions for your API, then use the NonStop DDL compiler to regenerate language-specific (C/C++, COBOL, etc.) header files that correspond to the new schema. Finally, it may also be necessary to adjust your client application source code to account for the schema changes.
Here's the DDL that's generated from the schema above.
DEF MY-SAMPLE.
02 PRICE TYPE BINARY 32,2.
02 QUANTITY TYPE BINARY 32.
02 PI TYPE BINARY 64,15.
02 AVAGADRO TYPE FLOAT 64.
END.
C/C++ Programming Considerations
Using the DDL source above and the NonStop DDL compiler, the following C/C++ header definition is created:
#include <tnsint.h>
typedef struct __my_sample
{
__int32_t price;
__int32_t quantity;
long long pi;
double avagadro;
} my_sample_def;
However, the following warnings are issued due to the fact the scaled integers are not natively supported in C/C++.
*** WARNING *** C OUTPUT DIAGNOSTICS:
*** WARNING *** Unsupported data type in element PRICE
*** WARNING *** Unsupported data type in element PI
Your client application can still manipulate scaled integers as shown below:
my_sample_def sample;
/* constructing values */
int dollars;
int cents;
sample.price = dollars * 100 + cents;
int whole = 3;
longlong fraction = 141592653589793;
sample.avagadro = whole * 1000000000000000 + fraction;
/* deconstructing values */
dollars = sample.price / 100;
cents = sample.price % 100;
whole = (int)( sample.avagadro / 1000000000000000 );
fraction = sample.avagadro % 1000000000000000;
You can also use Guardian System Procedures FORMATCONVERTX / FORMATDATAX to handle input/output for scaled integers in C programs.
COBOL Programming Considerations
Using the DDL source above and the NonStop DDL compiler, the following COBOL definition is created:
01 MY-SAMPLE.
02 PRICE PIC S9(7)V9(2) COMP.
02 QUANTITY NATIVE-4.
02 PI PIC S9(3)V9(15) COMP.
02 AVAGADRO PIC X(8).
COBOL supports scaled integers natively. However, the following warnings are issued due to the fact that floating point values are not supported in COBOL.
*** WARNING *** COBOL 85 OUTPUT DIAGNOSTICS:
*** WARNING *** Unsupported data type in element AVAGADRO
You can use Guardian System Procedures FORMATCONVERTX / FORMATDATAX to handle input/output for floating point numbers in COBOL programs.