The glue and impl classes for generated endpoints

The REST endpoint generator creates and modifies a series of files that define logic for how the endpoints interact with the application.

  • The apiconfig file is a "glue" file. It maps both the element resource and collection resource to a Gosu "Resource" file. For collection resources, this optionally provides a default sort order.
  • There are two "impl" files that define implementation details.
    • The <collection>Resource.gs file is a Gosu file that defines required behaviors for working with collections. This includes behaviors such as how to retrieve the collection from the database and how to create a minimal child element.
    • The <element>Resource.gs file is a Gosu file that defines required behaviors for working with elements. This includes behaviors such as how to initialize a new element and how to delete one.

In most cases, the files and modifications made by the REST endpoint generator are not complete. Developers must provide additional code. The places where additional coding is needed are flagged with the following comment:

// TODO RestEndpointGenerator : <context>

You can search for these "TODO comments" in Studio and complete the configuration. The remainder of this topic explains the configuration needed in every glue and impl file.

Configuring the apiconfig file

Cloud API has multiple files whose name ends in apiconfig.yaml. The shared_ext-1.0.apiconfig.yaml file is the one most relevant to generated endpoints. This file maps both element resource and collection resources to a Gosu Resource file. The shared ext apiconfig file also defines any default sort order for collections.

The REST endpoint generator automatically modifies this shared ext apiconfig file to map element and collection resources to respective Gosu Resource files, but it does not add the default sort order. Guidewire recommends adding default sorts for all custom collection resources, as this provides a deterministic response payload.

Glue code added by the REST endpoint generator

the REST endpoint generator adds glue code for every element and collection, which maps the resource to its Gosu Resource file. For example if you generate endpoints for CustomEntity_Ext, the following is added to the shared apiconfig file:

CustomEntitiesExt:
  resource: gw.rest.ext.cc.claim.v1.claims.customentityext.CustomEntitiesExtResource
CustomEntityExt:
  resource: gw.rest.ext.cc.claim.v1.claims.customqentityext.CustomEntityExtResource

You can add default sort orders to each resource declaration. These are declared using a defaultSort: property under the resource: property.

Determining which fields can be used for sort order

To use a given field in a default sort order, the field must be declared a sortable in the schema definition.

For example, the following is a portion of the schema description for the CustomEntity_Ext resource.
"definitions":
  "CustomEntity_Ext": {
    "properties": {
      "customDescription": { 
        ...
        "sortable": true 
        },
      "customDueDate": { 
        ...
        } 
      }, 

Note that the customDescription field includes the  "sortable": true  expression, but the  customDueDate  field does not. This means that you can sort on  customDescription, but not  customDueDate.

Ascending order

To define ascending sort order, add - <attributeName> to the defaultSort: property.

For example, the following defines a default ascending sort order based on customDescription:

CustomEntitiesExt: 
  resource: gw.rest.ext.cc.claim.v1.claims.customentityext.CustomEntitiesExtResource 
  defaultSort: 
    - customDescription 

Descending order

To define descending sort order, add – "-<attributeName>" to the defaultSort: property.

For example, the following defines a default descending sort order based on customDescription:

CustomEntitiesExt: 
  resource: gw.rest.ext.cc.claim.v1.claims.customentityext.CustomEntitiesExtResource 
  defaultSort: 
    - "-customDescription" 

Multiple sort criteria

To define multiple sort criteria, list each attribute on separate lines. Members are sorted by the first criteria. Then, for any members with the same value for the first criteria, those members are sorted based on the second criteria, and so on.

For example, the following defines a default sort order based on entryType ascending and then by typeField descending:

CustomEntitiesExt: 
  resource: gw.rest.ext.cc.claim.v1.claims.customentityext.CustomEntitiesExtResource 
  defaultSort: 
    - entryType 
    - "-typeField"

Configuring the element resource file

The element resource file contains implementation code used to manipulate an element resource.

The name of this file is <elementResource>Resource.gs. For most APIs, the file is in the gw.rest.ext.pc.<api>.<ancestor>.<resource> package. For example, when generating endpoints for a CustomEntity_Ext data model entity in the Account API whose ancestor is Account:

  • The element file is named CustomEntityExtResource.gs.

  • It is in the gw.rest.ext.pc.account.v1.accounts.customentityext package.

However, if the endpoints have been added to the Job API, then the resource files are created in the policyperiod package. For example, when generating endpoints for a CustomEntity_Ext data model entity in the Job API whose ancestor is Activity:

  • The element file is named CustomEntityExtResource.gs.
  • It is in the gw.rest.ext.pc.policyperiod.v1.activities.customentityext package.

You must modify the following getters and methods in the class in the following ways.

The init method

The init method initializes a new instance of this resource. It also ensures that the element of this resource is a child of the element of its parent resource.

In most cases, the example code provided is sufficient. It requires only uncommenting the method code and defining the parent foreign key.

For example, suppose your child element uses account as its parent resource. The uncommented method code looks like this:
override function init(parent : CustomEntityExtResource, elementId : String) {
  super.init(parent, elementId)
  validateParentChildConsistency(this.Parent.Parent.Element, this.Element.Account)
}

The delete method

The delete method deletes the resource, and it can provide an exception to the delete method from a business standpoint.

In most cases, the example code provided is sufficient. It requires only uncommenting the method code. For example, the uncommented method code looks like this:

override function delete() {
  this.Element.remove()
}

The CanEditException getter

The CanEditException getter determines whether the resource is editable from a business standpoint. If the resource is editable, the getter returns null. If the resource is uneditable, the getter returns a CanEditException.

For example, suppose the resource has an ExpirationDate field and edits can be made only before the expiration date.

  • If today's date is on or before the ExpirationDate, the getter returns null.
  • If today's date is after the ExpirationDate, the getter returns a LocalizedExceptionUtil.operationNotCurrentlyAllowedException

The following code illustrates this:

override property get CanEditException() : RestRequestException {
  var today = Calendar.getInstance().getTime();
  if (this.CustomEntity_Ext.ExpirationDate > today)
    return null
  else
    return LocalizedExceptionUtil.operationNotCurrentlyAllowedException
}

In most cases, you do not need constraints on editing the resource based on its business state, and the getter always returns null. For example:

override property get CanEditException() : RestRequestException  { 
  return null 
} 
Note: The purpose of this getter is to allow or prevent edits based solely on the business state of the resource. It is not intended to control authorization. For more information on controlling authorization, see Configuring authorization for generated endpoints.

The CanDeleteException getter

The CanDeleteException getter determines whether the resource can be deleted from a business standpoint. If the resource can be deleted, the getter returns null. If the resource cannot be deleted, the getter returns a CanEditException.

For example, suppose the resource has an ExpirationDate field and can be deleted only before the expiration date.

  • If today's date is on or before the ExpirationDate, the getter returns null.

  • If today's date is after the ExpirationDate, the getter returns a LocalizedExceptionUtil.operationNotCurrentlyAllowedException.

The following code illustrates this:

override property get CanDeleteException() : RestRequestException { 
  var today = Calendar.getInstance().getTime(); 
  if (this.CustomEntity_Ext.ExpirationDate > today) 
    return null 
  else 
    return LocalizedExceptionUtil.operationNotCurrentlyAllowedException() 
} 

In most cases, you do not need constraints on viewing the resource based on its business state, and the getter always returns null. For example:

override property get CanViewException() : RestRequestException { 
    return null 
} 
Note: The purpose of this getter is to allow or prevent edits based solely on the business state of the resource. It is not intended to control authorization. For more information, see Configuring authorization for generated endpoints.

The CanViewException getter

The CanViewException getter determines whether the resource is viewable from a business standpoint. If the resource is viewable, the getter returns null. If the resource is not viewable, the getter returns a CanViewException.

For example, suppose the resource has an ExpirationDate field and can be viewed only before the expiration date.

  • If today's date is on or before the ExpirationDate, the getter returns null.

  • If today's date is after the ExpirationDate, the getter returns a LocalizedExceptionUtil.operationNotCurrentlyAllowedException.

The following code illustrates this:

override property get CanViewException() : RestRequestException { 

  var today = Calendar.getInstance().getTime(); 
  if (this.CustomEntity_Ext.ExpirationDate > today) 
    return null 
  else 
    return LocalizedExceptionUtil.operationNotCurrentlyAllowedException() 
} 

In most cases, you do not need constraints on viewing the resource based on its business state, and the getter always returns null. For example:

override property get CanViewException() : RestRequestException { 
    return null 
} 
Note:

The purpose of this getter is to allow or prevent views based solely on the business state of the resource. It is not intended to control authorization. For more information, see Configuring authorization for generated endpoints.

Configuring the collection resource file

The collection resource file contains implementation code that manipulates the collection resource.

The name of this file is <collectionResource>Resource.gs. The file is located in the gw.rest.ext.pc.<api>.<ancestor>.<resource> package. For example, when generating endpoints for a CustomEntities_Ext data model entity in the Account API whose ancestor is Account:

  • The element file is named CustomEntitiesExtResource.gs.

  • It is in the gw.rest.ext.pc.account.v1.accounts.customentityext package.

You must modify the following getters and methods in the class in the following ways.

Note: The authorization layer is responsible for determining which resources the caller can access based on who the caller is. The following methods and getters are not intended to control authorization. For more information on controlling authorization, see Configuring authorization for generated endpoints.

The loadValues method (stream-backed collections only)

The loadValues method converts the collection resource array into a stream object. It also populates the response payload with the stream-backed collection.

For example, suppose the parent of CustomEntitities_Ext has an array of CustomEntitities_Ext. This method returns that array converted into a stream. The following code illustrates this:

protected override function loadValues() : Stream<Object> { 
  return this.Parent.Element.getCustomEntities_Ext().stream() 

If the parent does not have an array of the custom entity, then you must write Gosu code to construct an array or list manually and then convert it into a stream.

The buildBaseQuery method (query-backed collections only)

The buildBaseQuery method creates a Gosu query that returns the collection resource related to the parent resource.

For example, suppose the parent of CustomEntity_Ext is Account. This method needs to return all CustomEntity_Ext instance associated with the relevant account. following code illustrates this:

protected override function buildBaseQuery() : IQueryBeanResult<CustomEntity_Ext> { 
  return Query.make(entity.CustomEntity_Ext) 
      .compare(CustomEntity_Ext#Account, Relop.Equals, this.Parent.Element) 
      .select()

The canViewException getter

The canViewException getter determines whether the collection resource is viewable from a business standpoint. If the collection resource is viewable, the getter returns null. If the collection resource is not viewable, the getter returns a CanViewException.

In most cases, you do not need constraints on viewing the resource based on its business state. In this case, the getter always returns null. For example:

override property get CanViewException() : RestRequestException { 
    return null

The canCreateException getter

The canCreateException getter determines whether the collection resource can be created from a business standpoint. If the collection resource is createable, the getter returns null. If the collection resource is not createable, the getter returns a CanCreateException.

If there are no constraints on creating the resource based on any business state, then the getter always returns null.

The createMinimalChildElement method

The createMinimalChildElement method is used for POSTs on the collection resource. It creates a new instance of the entity and attaches it to its parent.

In most cases, the example code as shown below is sufficient. However, if there is additional initialization logic, it can be defined here.

override function createMinimalChildElement(attributes : DataAttributes) : CustomEntity_Ext { 
  var customEntity_Ext = new CustomEntity_Ext() 
  customEntity_Ext.Account = this.Parent.Element 
  return customEntity_Ext