Skip to content

View Templates

Rajesh Rathnam edited this page Apr 10, 2019 · 1 revision

Requirement

When a READ or SEARCH call hits the registry, all the fields associated with the subject are returned. We wanted to provide a way to control this and return only a select set of fields and optionally transform it. These view templates could be directly associated with some logic in the higher layers of the workflow, to say 'allow this administrators to fetch all records', whereas 'allow employees to fetch only their individual attributes'.

View templates are introduced to help us with this need. From an API front, the following are the requirements:

Ability to reference an identifier to view template (dynamic) in READ api Ability to supply a json view template (dynamic) in READ api Ability to reference an identifier to view template (dynamic) in SEARCH api Ability to supply a json view template (dynamic) in SEARCH api Soft requirements

The default READ will fetch ALL attributes associated with the record. There is no expression needed to fetch all attributes of the record.

View template format

The definition of any subject of interest to be stored in the registry is expressed using json-schema. A sample schema is provided below for reference (json document). We propose that the view template must also be a json.

Every view template, statically configured must be placed in registry/src/main/resources/views/ folder. Each json file underneath this folder would be treated as an 'active' or 'live' template that could be referenced in the API.

We propose it to be like the following. The inspiration is from swagger.io (OpenAPI yaml format) and gels with a similar format used to define the subject schema definition.

Note

  • "$comment" field has been used only for explanation purposes. Not part of the view template schema.
  • "" - string enclosed in angle brackets indicate a variable.
  • Every field value is suffixed with OPTIONAL or MANDATORY - self-descriptive
  • It is intentional that there is no "id" attribute. Providing that leads to other nuances, primarily how do we ensure they are not duplicates across many view templates. So, it is best considered, filename is the identifier.
{
   "fields": [
    {
       "name": "<fieldName>",
       "display": boolean_default_true_OPTIONAL,
       "function" : string_OPTIONAL,
       "viewTemplateName": string_OPTIONAL,
       "fetchType": "eager | lazy (default) _OPTIONAL"
    } 
  },
  "functionDefinitions": [ 
      {
          	"name" : "<function_name_MANDATORY>",
          	"result": "<expression_to_calculate_or_compute_or_transform_argN_OPTIONAL>",
			"provider" "<absolute_class_name_OPTIONAL>",
    	    "$ref": "<path_to_function_definition_in_another_template_OPTIONAL>",
            "$comment": {
                  "One of result | provider | $ref is mandatory
			}
      }
  ]
}

Example

{
  "subject": "Person",
  "fields": [
    { 
		"name": "name"
    },
    {
		"name": "nationalIdentifier",
        "display": false,
        "$comment": "This field is not displayable, but needed for internal referencing"
    },
    {
		"name": "uniqName",
        "function": "#/functionDefinitions/concat($name, $nationalIdentifier)",
        "$comment": "This is a virtual field not defined in the schema"
    },
    {
        "name": "vehicles",
        "$comment": "Nested child entity which may be of interest",
        "fetchType": "eager",
        "viewTemplateName": "vehicleNameView.json"
    }
  },
  "functionDefinitions": [ 
      {
          	"name" : "concat",
          	"result": "arg1 + \" : \" + arg2"
          	"$comment": "arg1 and arg2 will be populated with parameter values at runtime"
      },
      {
           	"name" : "userDefinedConcat",
           	"provider": "user.opensaber.registry.utils.MySplConcatenator",
		 	"$comment" : "Complex operations that cannot be expressed easily in an in-line function definition can be implemented as a class. "
      },
      {
           	"name" : "customDefinedConcat",
           	"$ref": "AnotherViewTemplate.json#functionDefinitions/customDefinedConcat"
			"$comment": "The functions defined in another template can be reused".
      }
  ]
}

Interface IViewFunctionProvider

public T abstract doAction(List<Object> values)
A list of objects (ordered) are passed to the function. arg1 will appear first in the list, followed by arg2 and so on. The adopter can choose to implement the transformation as he/she wishes. 

Example

Refer to tests in the module for using interface - here

Future plan

The current usage of the View Templates is only at the presentation layer. All the attributes of the record are pulled up from the database and then data is either masked or transformed. It may be useful to use View Templates much below the presentation layer. Our proposal is to take advantage of it to lessen the query load at the database level; query only attributes that have been sought - no more no less.