Tutorial: Extending a data model entity and its API resource

This tutorial assumes you have set up your environment with Postman and the correct sample data set. For more information, see Tutorial: Set up your Postman environment.

In this tutorial, you will extend a base configuration data model entity with additional fields. You will then configure the corresponding API resource with a set of associated properties, one for each extension field. The data model extensions are done through Guidewire Studio. This tutorial assumes that you are familiar with working in Studio.

Scenario

You have been asked to create a resource extension for the Activity resource in the Common API. That resource is based on the ClaimCenter Activity entity. You are going to extend resource properties to support the following entity fields:

Entity field name Resource property name Value type Support POST and PATCH?
ActivityClass activityClass_Ext typekey to ActivityClass typelist
CreateTime createTime_Ext datetime
CreateUser createUser_Ext foreign key to User entity
ShortSubject shortSubject_Ext varchar (10) yes
IsAutogenerated_Ext (user-created field extension) isAutogenerated_Ext bit yes

Notice that the last entry is a custom entity field extension. You will begin by creating that field in Studio. You will then configure the resource, mapping, and updater extensions to make these properties available through the system API. Lastly, you will verify the resource extension in Swagger UI and Postman.

Create an entity field extension

In order to make a custom entity extension accessible through a system API, that extension first. You can create a custom entity extension by doing the following:

  1. In Studio, open the Activity entity for editing. You can find that file at Project > configuration > config > Extensions > Entity > Activity.etx.
  2. Click +, and then select column.
  3. In the new column, enter the following name and value pairs:
  4. In the name field, enter IsAutogenerated_Ext
  5. In the type field, enter bit
  6. In the nullok field, enter true
  7. Save the file.
  8. To integrate your changes, start the development server in debug mode by selecing Run > Debug ‘Server’.
  9. To verify your work, regenerate the Data Dictionary for ClaimCenter, and then confirm the presence of this extension in the dictionary.

Extend the schema

  1. In Studio, open the schema extension file associated with the Common API.

    This file is located at Integration > schemas > ext > common > v1 > common_ext-1.0.schema.json.

    {
      "$schema": "http://json-schema.org/draft-04/schema#",
      "x-gw-combine": [
        "gw.content.cc.common.v1.common_content-1.0",
        "ext.framework.v1.framework_ext-1.0"
      ],
      "definitions": {}
      }
    }
  2. In the definitions field, create a schema definition extension for Activity, and add to this a properties attribute.
    {
      . . .
      "definitions": {
        "Activity": {
          "properties": {}
        }
      }
    }
  3. Within the properties attribute, create fields for each of the resource properties to be extended, as outlined in the “Scenario” section previously.
    {
      . . .
      "definitions": {
        "Activity": {
          "properties": {
            "activityClass_Ext": {},
            "createTime_Ext": {},
            "createUser_Ext": {},
            "shortSubject_Ext": {},
            "isAutogenerated_Ext": {}
          }
        }
      }
    }
  4. Within the activityClass_Ext property field, add a property value type for typekey.

    The typekey type is defined in the schema by a URI reference. To set the property value type, enter a $ref attribute and assign it a value of #/definitions/TypeKeyReference.

    Additionally, the typekey must be associated with a typelist. To set the typelist, add a x-gw-extensions attribute to the property, and then assign the appropriate typelist to the typelist field. In this example, the typelist is ActivityClass.

    The following code block depicts the completed property field:

    {
      . . .
      "definitions": {
        "Activity": {
          "properties": {
            "activityClass_Ext": {
              "$ref": "#/definitions/TypeKeyReference",
              "x-gw-extensions": {
                "typelist": "ActivityClass"
              }
            },
            . . .      }
        }
      }
    }
  5. In the createTime_Ext property field, add a property value type for datetime.

    To set the property value type, enter a type attribute and assign it a value of string. Next, add a format attribute and assign it a value of date-time.

    The following code block depicts the completed property field:

    {
      . . .
      "definitions": {
        "Activity": {
          "properties": {
            . . .
            "createTime_Ext": {
              "type": "string",
              "format": "date-time"
            },
            . . .      }
        }
      }
    }
  6. In the createUser_Ext property field, add a property value type for object.

    You can declare a property value type for an object by adding a $ref attribute to the resource property and assigning it a URI reference for an inlined resource (for details, refer to “The attributes section” in this guide). In this instance, enter a $ref attribute and assign it a value of #/definitions/SimpleReference.

    The following code block depicts the completed property field:

    {
      . . .
      "definitions": {
        "Activity": {
          "properties": {
            . . .
            "createUser_Ext": {
              "$ref": "#/definitions/SimpleReference"
            },
            . . .
          }
        }
      }
    }
  7. In the shortSubject_Ext property field, add a property value type for string.

    To set the property value type, enter a type attribute and assign it a value of string.

    The following code block depicts the completed property field:

    {
      . . .
      "definitions": {
        "Activity": {
          "properties": {
            . . .
            "shortSubject_Ext": {
              "type": "string"
            },
            . . .
          }
        }
      }
    }
  8. In the isAutogenerated_Ext property field, add a property value type for bit.

    To set the property value type, enter a type attribute and assign it a value of boolean.

    The following code block depicts the completed property field:

    {
      . . .
      "definitions": {
        "Activity": {
          "properties": {
            . . .
            "isAutogenerated_Ext": {
              "type": "boolean"
            }
          }
        }
      }
    }
  9. Save your changes.

Extend the mapper

  1. In Studio, open the mapper extension file associated with the Common API.

    This file is located at Integration > mappings > ext > common > v1 > common_ext-1.0.mapping.json.

    The base file appears as follows:

    {
      "schemaName": "ext.common.v1.common_ext-1.0",
      "combine": [
        "gw.content.cc.common.v1.common_content-1.0",
        "ext.framework.v1.framework_ext-1.0"
      ],
      "mappers": {}
    }
  2. In the mappers field, create a mapper extension for Activity.
    {
      . . .
      "mappers": {
        "Activity": {}
      }
    }
  3. In the Activity mapper extension, add a schemaDefinition property and give it the value Activity. This associates the mapper with the Activity resource.
    {
      . . .
      "mappers": {
        "Activity": {
          "schemaDefinition": "Activity"
        }
      }
    }
  4. Add a root property, and give it the value of entity.Activity. This associates the Activity resource with the ClaimCenter Activity entity.
    {
      . . .
      "mappers": {
        "Activity": {
          "schemaDefinition": "Activity",
          "root": "entity.Activity"
        }
      }
    }
  5. Add a properties property, and within that create fields for each of the properties that you added previously to the schema definition extension.
    {
      . . .
      "mappers": {
        "Activity": {
          "schemaDefinition": "Activity",
          "root": "entity.Activity",
          "properties": {
            "activityClass_Ext": {},
            "createTime_Ext": {},
            "createUser_Ext": {},
            "shortSubject_Ext": {},
            "isAutogenerated_Ext": {}
          }
        }
      }
    }
  6. Configure the activityClass_Ext property.
    1. Add a path attribute and assign it the value Activity.ActivityClass.

      This maps the resource property to the ActivityClass entity field.

    2. Add a mapper attribute and assign it the value #/mappers/TypeKeyReference.

      Any property whose type is declared by a URI reference must have a mapping set to a URI reference for the related mappers schema.

    The following code block depicts the completed property field:

    {
      . . .
      "mappers": {
        "Activity": {
          "schemaDefinition": "Activity",
          "root": "entity.Activity",
          "properties": {
            "activityClass_Ext": {
              "path": "Activity.ActivityClass",
              "mapper": "#/mappers/TypeKeyReference"
            },
            . . .
          }
        }
      }
    }
  7. In the createTime_Ext property, add a path attribute and assign it the value Activity.CreateTime.

    This maps the resource property to the CreateTime entity field.

    The following code block depicts the completed property field:

    {
      . . .
      "mappers": {
        "Activity": {
          "schemaDefinition": "Activity",
          "root": "entity.Activity",
          "properties": {
            . . .
            "createTime_Ext": {
              "path": "Activity.CreateTime"
            },
            . . .
          }
        }
      }
    }
  8. Configure the createUser_Ext property.
    1. Add a path attribute and assign it the value Activity.CreateUser.

      This maps the resource property to the CreateUser entity field.

    2. Add a mapper attribute and assign it the value #/mappers/SimpleReference.

      Any property whose type is declared by a URI reference must have a mapping set to a URI reference for the related mappers schema.

    The following code block depicts the completed property field:

    {
      . . .
      "mappers": {
        "Activity": {
          "schemaDefinition": "Activity",
          "root": "entity.Activity",
          "properties": {
            . . .
            "createUser_Ext": {
              "path": "Activity.CreateUser",
              "mapper": "#/mappers/SimpleReference"
            },
            . . .
          }
        }
      }
    }
  9. In the shortSubject_Ext property, add a path attribute and assign it the value Activity.ShortSubject.

    This maps the resource property to the ShortSubject entity field.

    The following code block depicts the completed property field:

    {
      . . .
      "mappers": {
        "Activity": {
          "schemaDefinition": "Activity",
          "root": "entity.Activity",
          "properties": {
            . . .
            "shortSubject_Ext": {
              "path": "Activity.ShortSubject"
            },
            . . .
          }
        }
      }
    }
  10. In the isAutogenerated_Ext property, add a path attribute and assign it the value Activity.IsAutogenerated_Ext.

    This maps the resource property to the IsAutogenerated_Ext entity field.

    The following code block depicts the completed property field:

    {
      . . .
      "mappers": {
        "Activity": {
          "schemaDefinition": "Activity",
          "root": "entity.Activity",
          "properties": {
            . . .
            "isAutogenerated_Ext": {
              "path": "Activity.IsAutogenerated_Ext"
            }
          }
        }
      }
    }
  11. Save your changes.

Extend the updater

For the updater, you only need to add resource properties that can be updated by a POST or PATCH operation. If a resource extension does not have any such properties, then it is not necessary to create an updater extension.

To create an updater that supports POST or PATCH operations for the isAutogenerated_Ext properties, follow these steps.

  1. In Studio, open the updater extension file associated with the Common API.

    This file is located at Integration > updaters > ext > common > v1 > common_ext-1.0.updater.json.

    The base file appears as follows:

    {
      "schemaName": "ext.common.v1.common_ext-1.0",
      "combine": [
        "gw.content.cc.common.v1.common_content-1.0",
        "ext.framework.v1.framework_ext-1.0"
      ],
      "updaters": {}
    }
  2. In the updaters field, create an updater extension for Activity.
    {
      . . .
      "updaters": {
        "Activity": {}
      }
    }
  3. In the Activity updater extension, add a schemaDefinition property and give it the value Activity.

    This associates the updater with the Activity resource.

    {
      . . .
      "updaters": {
        "Activity": {
          "schemaDefinition": "Activity"
        }
      }
    }
  4. Add a root property, and give it the value of entity.Activity.

    This associates the Activity resource with the ClaimCenter Activity entity.

    {
      . . .
      "updaters": {
        "Activity": {
          "schemaDefinition": "Activity",
          "root": "entity.Activity"
        }
      }
    }
  5. Add a properties property, and within that create a field for each of the supported properties as defined in the schema definition extension.
    {
      . . .
      "updaters": {
        "Activity": {
          "schemaDefinition": "Activity",
          "root": "entity.Activity",
          "properties": {
            "shortSubject_Ext": {},
            "isAutogenerated_Ext": {}
          }
        }
      }
    }
  6. In the isAutogenerated_Ext property, add a path attribute and assign it the value Activity.IsAutogenerated_Ext.

    This maps the resource property to the IsAutogenerated_Ext entity field, enabling property data to be written to the InsuranceSuite database.

    The following code block depicts the completed property field:

    {
      . . .
      "updaters": {
        "Activity": {
          "schemaDefinition": "Activity",
          "root": "entity.Activity",
          "properties": {
            "isAutogenerated_Ext": {
              "path": "Activity.IsAutogenerated_Ext"
            },
            . . .
          }
        }
      }
    }
  7. In the shortSubject_Ext property, add a path attribute and assign it the value Activity.ShortSubject.

    This maps the resource property to the ShortSubject entity field, enabling property data to be written to the InsuranceSuite database.

    The following code block depicts the completed property field:

    {
      . . .
      "updaters": {
        "Activity": {
          "schemaDefinition": "Activity",
          "root": "entity.Activity",
          "properties": {
            . . .
            "shortSubject_Ext": {
              "path": "Activity.ShortSubject"
            }
          }
        }
      }
    }
  8. Save your changes.

Verify the extended resource

After creating the schema definition extension, you can review the revised schema definition in Swagger UI.

  1. Launch Swagger UI, and then load the Common API.
  2. Select the GET /common/v1/activities/{activityId} endpoint.
  3. Under Responses, select the Model view.
  4. In the Activity schema associated with the data.attributes section, verify the presence of the extended properties.

Additionally, you can test drive the revised schema definition using Postman and some sample data. This tutorial assumes you have set up your environment with Postman and the correct sample data set. For more information, see the Cloud API Business Flows and Configuration Guide.

First, you can review the response object of a GET operation for the resource property extensions.

  1. In Postman, start a new request by clicking the + to the right of the Launchpad tab.
  2. Specify Basic Auth authorization using user aapplegate and password gw.
  3. Enter the following call, and then click Send:

    GET http://localhost:8080/cc/rest/common/v1/activites/cc:201

  4. Review the body of the response. It appears as follows:
    {
        "data": {
            "attributes": {
                "activityClass_Ext": {
                    "code": "task",
                    "name": "Task"
                },
                "activityPattern": "vendor_did_not_accept_work",
                "activityType": {
                    "code": "general",
                    "name": "General"
                },
                "assignedByUser": {
                    "displayName": "System User",
                    "id": "systemTables:2"
                },
                "assignedGroup": {
                    "displayName": "Auto1 - TeamA",
                    "id": "demo_sample:31"
                },
                "assignedUser": {
                    "displayName": "Andy Applegate",
                    "id": "demo_sample:1"
                },
                "assignmentStatus": {
                    "code": "assigned",
                    "name": "Assigned"
                },
                "createTime_Ext": "2020-06-04T22:10:00.091Z",
                "createUser_Ext": {
                    "displayName": "System User",
                    "id": "systemTables:2"
                },
                "description": "Follow up with vendor - work not accepted in timely manner",
                "dueDate": "2020-06-05T22:10:00.035Z",
                "escalated": false,
                "externallyOwned": false,
                "id": "cc:201",
                "importance": {
                    "code": "high",
                    "name": "High"
                },
                "mandatory": false,
                "priority": {
                    "code": "high",
                    "name": "High"
                },
                "recurring": false,
                "status": {
                    "code": "open",
                    "name": "Open"
                },
                "subject": "Follow up with vendor - work not accepted in timely manner"
            },
            . . .
            }
        }
    }

You can test the updater by executing a PATCH operation on the same resource:

  1. In Postman, start a new request by clicking the + to the right of the Launchpad tab.
  2. Specify Basic Auth authorization using user aapplegate and password gw.
  3. Enter the following call, but do not click Send:

    PATCH http://localhost:8080/cc/rest/common/v1/activites/cc:201

  4. Specify the request payload.
    1. In the first row of tabs (the one that starts with Params), click Body.
    2. In the row of radio buttons, select raw.
    3. At the end of the row of radio buttons, change the drop-down list value from Text to JSON.
    4. Paste the following into the text field underneath the radio buttons:
      {
      	"data": {
      		"attributes": {
      			"isAutogenerated_Ext": true,
      			"shortSubject_Ext": "shortsub"
      		}
      	}
      }
  5. Click Send. The response payload appears below the request payload.
    {
        "data": {
            "attributes": {
                "activityClass_Ext": {
                    "code": "task",
                    "name": "Task"
                },
                "activityPattern": "vendor_did_not_accept_work",
                "activityType": {
                    "code": "general",
                    "name": "General"
                },
                "assignedByUser": {
                    "displayName": "System User",
                    "id": "systemTables:2"
                },
                "assignedGroup": {
                    "displayName": "Auto1 - TeamA",
                    "id": "demo_sample:31"
                },
                "assignedUser": {
                    "displayName": "Andy Applegate",
                    "id": "demo_sample:1"
                },
                "assignmentStatus": {
                    "code": "assigned",
                    "name": "Assigned"
                },
                "createTime_Ext": "2020-06-04T22:10:00.091Z",
                "createUser_Ext": {
                    "displayName": "System User",
                    "id": "systemTables:2"
                },
                "description": "Follow up with vendor - work not accepted in timely manner",
                "dueDate": "2020-06-05T22:10:00.035Z",
                "escalated": false,
                "externallyOwned": false,
                "id": "cc:201",
                "importance": {
                    "code": "high",
                    "name": "High"
                },
                "isAutogenerated_Ext": true,
                "mandatory": false,
                "priority": {
                    "code": "high",
                    "name": "High"
                },
                "recurring": false,
                "shortSubject_Ext": "shortsub",
                "status": {
                    "code": "open",
                    "name": "Open"
                },
                "subject": "Follow up with vendor - work not accepted in timely manner"
            },
            . . .
        }
    }