REST Expanders 1.16.0
Miscellaneous
- The
SecurityRight
annotation 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.java
net.democritus.sys.Diagnostic
exception.getDiagnostics()
no longer added to errorModel
in mapException(exception)
methodDeleteFailedExceptionHandlerExpander
DeleteFailedExceptionHandler.java
net.democritus.sys.Diagnostic
exception.getDiagnostics()
no longer added to errorModel
in mapException(exception)
methodModificationFailedExceptionHandlerExpander
ModificationFailedExceptionHandler.java
net.democritus.sys.Diagnostic
exception.getDiagnostics()
no longer added to errorModel
in mapException(exception)
methodSearchResultExceptionHandlerExpander
SearchResultExceptionHandler.java
net.democritus.sys.Diagnostic
exception.getDiagnostics()
no longer added to errorModel
in mapException(exception)
methodServerErrorModelExpander
ServerErrorInfoModel.java
java.util.ArrayList
java.util.List
List<String> diagnostics
List<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-create
ModifyElementCommandExtensionExpander
execute()
: DataRef $dataElement.name$
→ DataRef $dataElement.name$DataRef
City
): DataRef city
→ DataRef cityDataRef
@after-modify
and custom-after-modify
UpdateElementCommandExtensionExpander
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-update
execute()
: DataRef $dataElement.name$
→ DataRef $dataElement.name$DataRef
City
): DataRef city
→ DataRef cityDataRef
@after-update
and custom-after-update
RemoveElementCommandExtensionExpander
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-delete
execute()
: DataRef $dataElement.name$
→ DataRef $dataElement.name$DataRef
City
): DataRef city
→ DataRef cityDataRef
@before-delete
and custom-before-delete
@after-delete
and custom-after-delete
ElementOutputListMapper
toExternal()
: $dataElement.name$OutputModel $dataElement.name$
→ $dataElement.name$OutputModel $dataElement.name$OutputModel
City
): CityOutputModel city
→ CityOutputModel cityOutputModel
@list-mapping
and custom-list-mapping
CreateDetailsFillerExpander
fill()
: $dataElement.name$Details $dataElement.name$
→ $dataElement.name$Details $dataElement.name$Details
City
): CityDetails city
→ CityDetails cityDetails
@fill
and custom-fill
fill$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-fill
fill$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-fill
fill$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$