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 "Resource" Gosu 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

The apiconfig file maps both element resource and collection resources to a Resource Gosu file. The apiconfig file can be used to define the order for your collection response payload.

The REST endpoint generator automatically modifies the apiconfig file to map element and collection resources to respective Resource Gosu files, but does not add the sort order for your response payload.

Guidewire recommends a default sort order for your collection resources to provide a consistent, deterministic response payload. Determine the object by which the response payload orders its collection by defining the default sort order.

Including default sorts in the .apiconfig file

The apiconfig file maps the collection and elements resources of your custom endpoint to its respective Resource Gosu files. For example,

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

Append defaultSort under the collection resource to determine the order the sortable attributes are sorted by in the response payload.

For a given endpoint, you can identify the attributes that are sortable by reviewing the API core schema file (<api_collection>_ext-1.0.schema.json) in the x-gw-extensions resource.If a field is sortable, then the schema description of the field includes the text: "sortable": true.

For example, the following is the schema description for the dueDate field returned by the Common API's  Activity definition.
"dueDate": { 
  "title": "Due date", 
  "description": "Date and time by which a person should complete the activity. If not 
completed by this time, the activity is considered overdue. Not applicable to activities 
that represent events rather than tasks.", 
  "type": "string", 
  "format": "date-time", 
  "x-gw-nullable": true, 
  "x-gw-extensions": { 
    "filterable": true, 
    "sortable": true 
  } 
}, 

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

You can define ascending or descending order via syntax; use - <attributeName> for ascending, and use – "-<attributeName>" for descending sort order. For example, if you wanted ascending sort order based on the customDescription attribute in your element and collection, use the following:

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

For descending sort order, use the following:

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

You can also use multiple attributes to further define the sort order; the first attribute initially defines the sort order, then the second attribute defines the order of those items, then additional attributes defines the order of those items, and so forth. For example, if you wanted to sort your response payload first by attribute entryType, and then sort by all the objects that use entryType by their typeField attribute, use the following:

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. The file is in the gw.rest.ext.cc.<api>.<ancestor>.<resource> package. For example, when generating endpoints for a CustomEntity_Ext data model entity in the Claim API whose ancestor is Claim:

  • The element file is named CustomEntityExtResource.gs.

  • It is in the gw.rest.ext.cc.claim.v1.claims.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, and ensures that this element resource is a child of the element of its parent resource.

In most cases, the example code provided is sufficient, and requires only uncommenting the method code and defining the parent foreign key. For example, your child element and its resource uses claim 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.Claim)
}

The delete method

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

In most cases, the example code provided is sufficient, and 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 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 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 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 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 used to manipulate a collection resource.

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

  • The element file is named CustomEntitiesExtResource.gs.

  • It is in the gw.rest.ext.cc.claim.v1.claims.customentityext package.

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

The loadValues method (stream-backed collections only)

The loadValues method converts the collection resource array into a Java stream object, and populates the response payload with the stream-backed collections

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.

Note: The purpose of this method is to construct the set of available elements as determined by the authorization layer. It is not intended to control authorization itself. For more information on controlling authorization, see Configuring authorization for generated endpoints.

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 Claim. This method needs to return all CustomEntity_Ext instance associated with the relevant claim. following code illustrates this:

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

Note: The purpose of this method is to construct the set of available elements as determined by the authorization layer. It is not intended to control authorization itself. For more information on controlling authorization, see Configuring authorization for generated endpoints.

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, and the getter always returns null. For example:

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

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

Note: The purpose of this getter is to prevent creation 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 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.

Note: The purpose of this getter is to prevent creation 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 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.Claim = this.Parent.Element 
  return customEntity_Ext