Integration mapping examples

How JSON schemas relate to integration mappings is easiest to see if you view them next to one another. In the following example are a simple schema named contact-1.0 and the integration mapping that corresponds to it:
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "definitions": {
    "Address": {
      "type" : "object",
      "properties" : {
        "addressLine1" : {
          "type" : "string"
        },
        "city" : {
          "type" : "string"
        },
        "state" : {
          "type" : "string",
          "x-gw-type" : "typekey.State"
        }
     }
  },
  "Contact" : {
    "type" : "object",
    "properties" : {
      "allAddresses": {
        "type": "array",
          "items": {
            "$ref": "#/definitions/Address"
          }
        },
        "displayName": {
          "type": "string"
        },
        "firstName": {
          "type": "string"
        },
        "lastName": {
          "type": "string"
        },
        "primaryAddress": {
          "$ref": "#/definitions/Address"
        },
        "subtype": {
          "type": "string",
          "x-gw-type": "typekey.Contact"
        }
      }
    }
  }
}
{
  "schemaName": "contact-1.0",
  "mappers": {
    "Address": {
      "schemaDefinition" : "Address",
      "root" : "entity.Address",
      "properties" : {
        "addressLine1" : {
          "path" : "Address.addressLine1"
        },
        "city" : {
          "path" : "Address.City"
        },
        "state" : {
          "path" : "Address.State"
        }
     }
  },
  "Contact" : {
    "schemaDefinition" : "Contact",
      "root" : "entity.Contact",
      "properties" : {
        "allAddresses": {
          "path" : "Contact.AllAddresses",
          "mapper" : "#/mappers/Address"
        },
        "displayName": {
          "path": "Contact.DisplayName"
        },
        "firstName": {
          "path": "(Contact as Person).FirstName",
          "predicate" : "Contact typeis Person"
        },
        "lastName": {
          "path": "(Contact as Person).FirstName",
          "predicate" : "Contact typeis Person"
        },
        "primaryAddress": {
          "path" : "Contact.PrimaryAddress",
          "mapper": "#/mappers/Address"
        },
        "subtype": {
          "path" : "Contact.Subtype"
        }
      }
    }
  }
}
The pieces match up as follows:
  • The schemaName property of the mapping file references the fully-qualified name of the JSON schema file. The schemaDefinition property within the Address and Contact mappers references definitions within the schema.
  • The properties on each mapper exactly match the set of schema properties on the associated schema definitions.
  • The Address mapper has a root type of entity.Address. Consequently, all path and predicate expressions on properties for the Address mapper have the symbol Address available with a type of entity.Address. Similarly, the Contact mapping properties all have the Contact symbol available to their Gosu expressions.
  • For scalar properties, the path expressions all evaluate to an object type that is compatible with the data type implied by the type/format/x-gw-type on the schema property. The ramifications include the following:
    • Address.addressLine1 is a String
    • Address.city is a String
    • Address.state is a typekey.State
    • Contact.displayName is a String
    • Contact.firstName is a String
    • Contact.lastName is a String
    • Contact.subtype is a typekey.Contact
  • For object or object array properties, the path expression returns something that matches the root type of the referenced mapper, which means the following:
    • Contact.allAddresses returns an entity.Address[]
    • Contact.primaryAddress returns an entity.Address
  • The Contact.firstName and Contact.lastName mapping properties use a predicate so that the path expression will only execute if the Contact is actually a Person. This arrangement allows the path expression to be cleaner. The arrangement also avoids awkward ternary expressions.