REST Expanders 1.16.0
Miscellaneous
- The SecurityRightannotation was moved from the shared layer to the control layer. It was never intended to be used outside the control layer.
SecurityRight annotation was moved from the shared layer to the control layer. It was never intended to be used outside the control layer.In previous versions of the main expanders, the commands were injected into the logic bean as a feature. Since we do not nest features, this made it impossible to implement commands from another expander bundle, such as the rest-expanders. This feature was integrated into the bean expander, allowing other bundles to now implement commands.
To solve this original issue, the rest-expanders injected some code into the custom anchors of the commands in the logic bean. This was never intended to be a permanent solution, but a temporary workaround to address this issue. Version 1.15.0 of the rest-expanders has a minimum dependency of version 4.12.0 of the main expanders, to be able to transition to actual feature injection for this purpose. As the previous code has now ended up in the harvest files of every project, the workaround has been inverted to remove the workaround code that was injected.
An example of the old injected code:
// anchor:custom-command-createEntity:start
// Default implementation generated by the REST expanders
commandResult = executeCreateEntityCommand(commandParameter);
// anchor:custom-command-createEntity:end
The code will be removed automatically if the endpoint still exists in the model and no code (other than whitespace) has been added in between the start anchor and the injected code.
The previous execute methods were added to avoid the code from being altered easily and make the transition more difficult. These have now been removed and the code they contained is now injected as part of the feature.
An example of the new injected feature code, which was previously in the execute method:
// @anchor:command-createEntity:start
commandResult = new CreateEntityCommandExtension().execute(commandParameter);
if (commandResult == null || commandResult.isError()) {
  sessionContext.setRollbackOnly();
}
// @anchor:command-createEntity:end
We are no longer exposing values in Diagnostic object directly through error payloads in the REST API. The reasoning behind this is that we do not want to expose diagnostic information directly to the end-user. As an alternative, all exceptions that are handled by the REST API that contain diagnostics now have their diagnostics output into the logs along with the information that was already logged previously. Given that this pertains to 5xx errors, these are technical errors that should not occur in production and will likely be handled by a developer. Any issues with input of data should already have been handled by the validation system. These errors which return diagnostics are only thrown when something unexpected has occurred. The diagnostics have more value to a developer rather than the end-user and are more easily accessed through the application logs.
A transient option jaxrs.transient.exposeDiagnostics.enable has been supplied to revert the behavior of the expanders for backwards compatibility. But keep in mind that this option will be removed in the future and has only been supplied for short-term compatibility if needed, allowing for planning to upgrade the codebase. The option will once again expose the diagnostics through the API, but they will also appear in the application logs.
The transient option jaxrs.transient.exposeDiagnostics.enable was removed in rest-expanders version 2.9.0.
The following expanders have been affected:
CreateFailedExceptionHandlerExpander
CreateFailedExceptionHandler.javanet.democritus.sys.Diagnosticexception.getDiagnostics() no longer added to errorModel in mapException(exception) methodDeleteFailedExceptionHandlerExpander
DeleteFailedExceptionHandler.javanet.democritus.sys.Diagnosticexception.getDiagnostics() no longer added to errorModel in mapException(exception) methodModificationFailedExceptionHandlerExpander
ModificationFailedExceptionHandler.javanet.democritus.sys.Diagnosticexception.getDiagnostics() no longer added to errorModel in mapException(exception) methodSearchResultExceptionHandlerExpander
SearchResultExceptionHandler.javanet.democritus.sys.Diagnosticexception.getDiagnostics() no longer added to errorModel in mapException(exception) methodServerErrorModelExpander
ServerErrorInfoModel.javajava.util.ArrayListjava.util.ListList<String> diagnosticsList<String> getDiagnostics()void setDiagnostics(List<String>)void addDiagnostic(String)ValidationException class was moved from the shared layer to the control layer. It was never intended to be used outside the control layer.Some names of variables and method arguments were qualified with specific suffixes in order to avoid obvious collisions with DataElement names. This problem occurs because these variable are named with a clear collision risk, because they are named simply after the element or with an existing suffix which risks collision with other variable names. One such example is a DataElement with name Command, which could collide with a frequently used variable name command, as $dataElement.name.firstToLower$ is also used as a variable in the same scope.
A transient option jaxrs.transient.useQualifiedNames.disable has been supplied to revert the behavior of the expanders for backwards compatibility. But keep in mind that this option will be removed in the future and has only been supplied for short-term compatibility if needed, allowing for planning to upgrade the codebase.
The transient option jaxrs.transient.useQualifiedNames.disable was removed in rest-expanders version 2.9.0.
The following expanders have been affected:
CreateElementCommandExtensionExpander
execute(): DataRef $dataElement.name$ → DataRef $dataElement.name$DataRef
City): DataRef city → DataRef cityDataRef@after-create and custom-after-createModifyElementCommandExtensionExpander
execute(): DataRef $dataElement.name$ → DataRef $dataElement.name$DataRef
City): DataRef city → DataRef cityDataRef@after-modify and custom-after-modifyUpdateElementCommandExtensionExpander
execute(): SearchResult<> $dataElement.name$Result → SearchResult<> $dataElement.name$SearchResult
City): SearchResult<> cityResult → SearchResult<> citySearchResult@before-update and custom-before-update@after-update and custom-after-updateexecute(): DataRef $dataElement.name$ → DataRef $dataElement.name$DataRef
City): DataRef city → DataRef cityDataRef@after-update and custom-after-updateRemoveElementCommandExtensionExpander
execute(): SearchResult<> $dataElement.name$Result → SearchResult<> $dataElement.name$SearchResult
City): SearchResult<> cityResult → SearchResult<> citySearchResult@before-delete and custom-before-delete@after-delete and custom-after-deleteexecute(): DataRef $dataElement.name$ → DataRef $dataElement.name$DataRef
City): DataRef city → DataRef cityDataRef@before-delete and custom-before-delete@after-delete and custom-after-deleteElementOutputListMapper
toExternal(): $dataElement.name$OutputModel $dataElement.name$ → $dataElement.name$OutputModel $dataElement.name$OutputModel
City): CityOutputModel city → CityOutputModel cityOutputModel@list-mapping and custom-list-mappingCreateDetailsFillerExpander
fill(): $dataElement.name$Details $dataElement.name$ → $dataElement.name$Details $dataElement.name$Details
City): CityDetails city → CityDetails cityDetails@fill and custom-fillfill$field.name$(): $dataElement.name$Details $dataElement.name$ → $dataElement.name$Details $dataElement.name$Details
City): CityDetails city → CityDetails cityDetails@fill-$field.name$ and custom-fill-$field.name$ModifyDetailsFillerExpander
fill(): $dataElement.name$Details $dataElement.name$ → $dataElement.name$Details $dataElement.name$Details
City): CityDetails city → CityDetails cityDetails@fill and custom-fillfill$field.name$(): $dataElement.name$Details $dataElement.name$ → $dataElement.name$Details $dataElement.name$Details
City): CityDetails city → CityDetails cityDetails@fill-$field.name$ and custom-fill-$field.name$UpdateDetailsFillerExpander
fill(): $dataElement.name$Details $dataElement.name$ → $dataElement.name$Details $dataElement.name$Details
City): CityDetails city → CityDetails cityDetails@fill and custom-fillfill$field.name$(): $dataElement.name$Details $dataElement.name$ → $dataElement.name$Details $dataElement.name$Details
City): CityDetails city → CityDetails cityDetails@fill-$field.name$ and custom-fill-$field.name$