Inheritance and abstract models
As codeBeamer is a heavily configurable tool and Swagger requires a defined structure, we had to rely heavily on inheritance. That's why you can find a lot of Abstract... models in our schema and the actual models can be derived in runtime based on tracker configuration.
Abstract models in the tracker schema
During discovering the API you can find multiple Abstract models defined as returned value. These models are depending on the configuration of the tracker.
For Example as of codeBeamer 10.1:
AbstractField can be implemented as:
- CountryField
- DateField
- ColorField
- MemberField
- DurationField
- DecimalField
- BoolField
- IntegerField
- LanguageField
- ReviewMemberReferenceField
- ReferenceField
- TableField
- TextField
- UrlField
- WikiTextField
- OptionChoiceField
- RepositoryChoiceField
- ProjectChoiceField
- TrackerChoiceField
- TrackerItemChoiceField
- UserChoiceField
|
AbstractReference can be implemented as:
- AttachmentReference
- AssociationTypeReference
- ChoiceOptionReference
- CommentReference
- FieldReference
- ProjectReference
- ReportReference
- RepositoryReference
- RoleReference
- TrackerPermissionReference
- TrackerReference
- TrackerTypeReference
- UserGroupReference
- UserReference
- TrackerItemReference
- WikiPageReference
|
AbstractFieldValue can be implemented as:
- TableFieldValue
- ChoiceFieldValue
- UrlFieldValue
- NotSupportedFieldValue
- BoolFieldValue
- ColorFieldValue
- CountryFieldValue
- DateFieldValue
- DecimalFieldValue
- DurationFieldValue
- IntegerFieldValue
- LanguageFieldValue
- TextFieldValue
- WikiTextFieldValue
- ReferredTestStepFieldValue
|
GET /v3/trackers/{trackerId}/schema
|
GET /v3/items/{itemId}
|
PUT /v3/items/{itemId}/fields
|
Discriminator property
The OpenAPI Specification defines the way how inheritance should be handled in the API definition: https://swagger.io/docs/specification/data-models/inheritance-and-polymorphism
In case of abstract models a discriminator property will tell what exact implementation is provided in the response.
The specification of AbstractField shows that each returned model will have a type property which refers to the model of the object:
"AbstractField": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "Id of a field",
"format": "int32"
},
"name": {
"type": "string",
"description": "Name of a field"
},
...
},
"description": "Abstract field",
"discriminator": {
"propertyName": "type"
}
},
So if for Example an integer field is returned the type parameter will tell the actual model of that object. It is the IntegerField implementation of the AbstractField model:
Definiton:
|
Actual payload:
{
"id": 0,
"name": "ID",
"type": "IntegerField",
"hidden": false,
"valueModel": "IntegerFieldValue",
"mandatoryInStatuses": []
}, |
Helper properties in the tracker schema
In case you are about to construct a customField value in the TrackerItem model the documentation tells that it will accept a list of AbstractFieldValue models:
To help to find out which model representation is need to be used for a specific field we have introduced a few helper properties: valueModel, referenceType and trackerItemField.
For Example
Here is the schema of a custom field:
{
"id": 1006,
"name": "Occurrence",
"description": "Frequency Issue occurred during testing",
"type": "OptionChoiceField",
"hidden": false,
"valueModel": "ChoiceFieldValue<ChoiceOptionReference>",
"mandatoryInStatuses": [
{
"id": 0,
"name": "Unset",
"type": "ChoiceOptionReference"
},
{
"id": 3,
"name": "New / Unassigned",
"type": "ChoiceOptionReference"
},
...
],
"multipleValues": false,
"options": [
{
"id": 0,
"name": "Unset",
"type": "ChoiceOptionReference"
},
{
"id": 1,
"name": "Always",
"type": "ChoiceOptionReference"
},
{
"id": 2,
"name": "Often",
"type": "ChoiceOptionReference"
}
...
],
"referenceType": "ChoiceOptionReference"
}
To select the desired option for this field we will need to construct a valueModel which contains a referenceType value.
In this case we will need to select the ChoiceFieldValue implementation of AbstractFieldValue as "valueModel": "ChoiceFieldValue..." from the schema above.
Looking up the definition in the Models section of the Swagger UI:
Knowing that type is our discriminator property we can construct the value model as follows:
{
"fieldId": 1006,
"name": "Occurrence",
"type": "ChoiceFieldValue",
"values": [ {some AbstractReference model} ]
},
To find out which AbstractReference model implementation can be used as a values item we can look up the "referenceType": "ChoiceOptionReference" property.
For choice option fields the available options are listed in the field schema:
"options": [
{
"id": 0,
"name": "Unset",
"type": "ChoiceOptionReference"
},
{
"id": 1,
"name": "Always",
"type": "ChoiceOptionReference"
},
{
"id": 2,
"name": "Often",
"type": "ChoiceOptionReference"
},
...
],
So selecting the second option, our final valueModel would look like this:
"customFields": [
{
"fieldId": 1006,
"name": "Occurrence",
"type": "ChoiceFieldValue",
"values": [
{
"id": 2,
"name": "Often",
"type": "ChoiceOptionReference"
}
]
}
]
Alternatively you can use the GET /v3/items/{itemId}/fields/{fieldId}/options endpoint which will list all references which can be set for a field for a specific tracker item.
In summary
There are three properties which can help you set values in the TrackerItem model:
- valueModel: defines the exact implementation of an AbstractFieldValue. It contains the name of the valueModel which needs to be populated in order to set a field value.
- referenceType: for choice fields it defines the type of the choice value. It contains the name of the AbstractReference implementation, which can be used as a values item in the ChoiceFieldValue model.
- trackerItemField: for built-in fields it defines the explicitly provided properties in the TrackerItem model. For Example there is a name property to set the Title of the item. The Title field definition will contain a trackerItemField: "name", entry.