Skip to main content

Serialization

Pre-requisite

Install @ewam/wam-cloud

npm i @ewam/wam-cloud
npm run ewam:cli -- --import ./node_modules/@ewam/wam-cloud/src --use-exit-code

Difficulty: Beginner

Introduction

When we need to expose APIs we usually have 2 options:

  1. Create a simplified model that will represent this data
  2. Serialize the data from the model directly

Option 1 has the following benefits:

  • what we want
  • the way we want

But has the following issue:

  • it is expensive to develop 💰
  • hard to maintain 😓

The second option will be discussed on how we can leverage model annotations with the option 2 with the 2 key benefits of option 1 😃!

Model

Let's take the simple model below of a contract. A contract has a list of coverages and a reference to a client.

Requirements

  • The variable productName shall be renamed product
  • The variables effecticeDate and underwritingStatus status shall not be part of the serialization
  • The list of coverage should be included
  • Only the subscriber reference should be given

Example :

{
"className":"aRT_Contract",
"id":"C1041744",
"status":"cActive",
"product":"Group Life",
"coverages":[
{
"className":"aRT_Coverage",
"coverageName":"Employee Term Life"
}
]
}

Implementation

All those requirements can be implemented via annotations on the model:

aRT_Contract
; aRT_Contract (aFullObject) (Def Version:3) (Implem Version:3)

class aRT_Contract (aRT_Master)

uses aRT_Coverage, aRT_Client, SerializationAnnotation

type tRT_status : (
[model(Text: 'Active')] cActive,
[model(Text: 'Pending')] cPending,
[model(Text: 'Terminated')] cTerminated
) multiLang

[Serialization(readOnly_: true)]
status : tRT_status
[Serialization(ignore: true)]
effectiveDate : Date
[Serialization(ignore: true)]
underwritingStatus : CString
[Serialization(name: 'product', required: true, readOnly_: true)]
productName : CString
coverages : listOf [O] aRT_Coverage inverse MyOwner
[Serialization(required: true)]
subscriber : refTo [P, A] aRT_Client

To serialize an object you need a factory aDataDefinitionFactory and a context aAdapterContext to set how you want to serialize/unserialize your data.

 function GetNewContract return aRT_Contract
uses aRT_Coverage, aRT_Client

var coverage : aRT_Coverage
var client : aRT_Client

new(_Result)
_Result.productName = 'Group Life'
new(coverage)
coverage.coverageName = 'Employee Term Life'
_Result.coverages[-1] = coverage
new(client)
client.AllocateFullId
client.name = 'Doe'
client.shortName = 'John'
_Result.subscriber = client
endFunc


procedure Serialize
uses aDataAdapter, aDataDocument, aSequenceType

var factory : aDataAdapterFactory
var context : aDataAdapterContext
var adapter : aDataAdapter
var document : aDataDocument
var contract : aRT_Contract
var output : Text

factory = Doc.wGetSystemAdapterFactory
context = factory.GetNewAdapterContext
contract = GetNewContract
adapter = factory.GetAdapterFor(contract.type)
;
if adapter <> Nil
new(document)
adapter.SerializeValue(@contract, document, context)
document.SetIndentation(True)
if Doc.JSON.StringifyText(document, output)
; => result is in output
output := ''
endIf
;
endIf
dispose(context)
endProc
!aRT_Contract 
id: C1041744
product: 'Group Life'
coverages:
- !aRT_Coverage
coverageName: 'Employee Term Life'
subscriber:
'$ref': '318767105_27'

Generating the json schema

One powerful feature of the adapter model is their ability to generate a schema. So here with the instruction :

 adapter.GenerateSchema(doc, context)

You will be able to generate the following:

{
"name":"aRT_Contract",
"title":"",
"type":"object",
"properties":{
"className":{
"type":"string"
},
"myImageM":{
"type":"any"
},
"UniqueIdentifier":{
"type":"string",
"maxLength":12
},
"id":{
"type":"string",
"maxLength":12
},
"status":{
"readOnly":true,
"type":"string",
"enum":["cActive","cPending","cTerminated"],
"enumNames":["Active","Pending","Terminated"]
},
"product":{
"readOnly":true,
"type":"string",
"maxLength":255
},
"coverages":{
"type":"array",
"items":{
"name":"aRT_Coverage",
"title":"",
"type":"object",
"properties":{
"className":{
"type":"string"
},
"myImageM":{
"type":"any"
},
"UniqueIdentifier":{
"type":"string",
"maxLength":12
},
"coverageName":{
"type":"string",
"maxLength":255
}
},
"required":["className"]
}
},
"subscriber":{
"type":"object",
"$ref":"model://aRT_Client"
}
},
"required":["className","product","subscriber"]
}
note

If you comment your model it will also appear in the documentation