Server-Side Events
TXDataServerModule published several events that you can use to implement additional server-side logic, customize XData behavior, among other tasks. You can use events, for example, to:
Implement custom authorization, refusing or accepting an operation based on the user credentials or any other context information;
Restrict/change the data returned to the client by TMS Aurelius CRUD Endpoints, by adding more filters to a query made by the user, for example;
Implement additional server-side logic, for example, performing extra operations after a resource is saved.
Events in XData are available in the Events property of the
TXDataServerModule object. Such
property refers to a TXDataModuleEvents (declared in unit
XData.Module.Events
) object with several subproperties, each to them
related to an event.
Read Using Events for more detailed info. You can also see real-world usage of events by checking the Authentication Example using JSON Web Token (JWT).
Events in TXDataModuleEvents
General-purpose events
Name | Description |
---|---|
OnModuleException | Occurs when an exception is raised during request processing. You can use it to provide custom error-handling. |
OnManagerCreate | Occurs when a TObjectManager instance is created to be used during request processing. You can use it to customize settings for the TObjectManager. |
Events of TMS Aurelius CRUD Endpoints
Name | Description |
---|---|
OnEntityGet | Occurs after an entity is retrieved, right before being sent to the client. |
OnEntityList | Occurs when the client queries an entity collection. |
OnEntityInserting | Occurs right before an entity creation. |
OnEntityInserted | Occurs right after an entity creation. |
OnEntityModifying | Occurs right before an entity update. |
OnEntityModified | Occurs right after an entity update. |
OnEntityDeleting | Occurs right before an entity delete. |
OnEntityDeleted | Occurs right after an entity delete. |
Using Events
Events in XData are available in the Events property of the
TXDataServerModule object. Such
property refers to a TXDataModuleEvents (declared in unit
XData.Module.Events
) object with several subproperties, each to them
related to an event.
For example, to access the OnEntityInserting event:
uses {...}, XData.Server.Module, XData.Module.Events;
// Module is an instance of TXDataServerModule object
Module.Events.OnEntityInserting.Subscribe(
procedure(Args: TEntityInsertingArgs)
begin
// Use Args.Entity to retrieve the entity being inserted
end
);
In a less direct way, using method reference instead of anonymous method:
uses {...}, XData.Server.Module, XData.Module.Events;
procedure TSomeClass.MyEntityInsertingProc(Args: TEntityInsertingArgs);
begin
// Use Args.Entity to retrieve the entity being inserted
end;
procedure TSomeClass.RegisterMyEventListeners(Module: TXDataServerModule);
var
Events: TXDataModuleEvents;
begin
Events := Module.Events;
Events.OnEntityInserting.Subscribe(MyEntityInsertingProc);
end;
Listeners are method references that receive a single object as a parameter. Such object has several properties containing relevant information about the event, and differ for each event type. Names of event properties, method reference type and arguments follow a standard. The event property is named "On<event>", method reference type is "T<event>Proc" and parameter object is "T<event>Args". For example, for the "EntityInserting" event, the respective names will be "OnEntityInserting", "TEntityInsertingProc" and "TEntityInsertingArgs".
All events in XData are multicast events, which means you can add several events handlers (listeners) to the same event. When an event occurs, all listeners will be notified. This allows you to add a listener in a safe way, without worrying if it will replace an existing listener that might have been set by other part of the application.
It's always safe to set the events before adding the module and running the server.
OnEntityGet Event
Occurs after an entity is retrieved, right before being sent to the client. This event is also fired when the client requests part of that entity, for example, individual properties of the entity, blob data, or associated entities.
Example:
Module.Events.OnEntityGet.Subscribe(
procedure(Args: TEntityGetArgs)
begin
// code here
end
);
TEntityGetArgs Properties:
Name | Description |
---|---|
Entity: TObject | The retrieved entity. |
Handler: TXDataBaseRequestHandler | The XData request processor object. |
OnEntityList Event
Occurs when the client queries an entity collection. This event is fired after the TCriteria object is built based on the client request, and right before the criteria is actually executed to retrieve the entities and sent to the client.
Example:
Module.Events.OnEntityList.Subscribe(
procedure(Args: TEntityListArgs)
begin
// code here
end
);
TEntityListArgs Properties:
Name | Description |
---|---|
Criteria: TCriteria | The Aurelius criteria built based on client request that will be used to retrieve the collections. You can modify the request here, adding extra filters, orders, etc., before it's executed and results are sent to the client. |
Handler: TXDataBaseRequestHandler | The XData request processor object. |
OnEntityInserting Event
Occurs right before an entity creation. This event happens in the middle of a database transaction, right before the entity is about to be created in the database.
Example:
Module.Events.OnEntityInserting.Subscribe(
procedure(Args: TEntityInsertingArgs)
begin
// code here
end
);
TEntityInsertingArgs Properties:
Name | Description |
---|---|
Entity: TObject | The entity being inserted. |
Handler: TXDataBaseRequestHandler | The XData request processor object. |
OnEntityInserted Event
Occurs after an entity is created. Note that, unlike OnEntityInserting Event, this event happens after the transaction is committed. There is no way to rollback the insertion of the entity, and any database operation here will be performed with no active transaction (unless you begin one manually).
Example:
Module.Events.OnEntityInserted.Subscribe(
procedure(Args: TEntityInsertedArgs)
begin
// code here
end
);
TEntityInsertedArgs Properties:
Name | Description |
---|---|
Entity: TObject | The entity which was created (inserted). |
Handler: TXDataBaseRequestHandler | The XData request processor object. |
OnEntityModifying Event
Occurs right before an entity update. This event happens in the middle of a database transaction, right before the entity is about to be updated in the database.
Example:
Module.Events.OnEntityModifying.Subscribe(
procedure(Args: TEntityModifyingArgs)
begin
// code here
end
);
TEntityModifyingArgs Properties:
Name | Description |
---|---|
Entity: TObject | The entity being modified. |
Handler: TXDataBaseRequestHandler | The XData request processor object. |
OnEntityModified Event
Occurs right after an entity update. Note that, unlike OnEntityModifying Event, this event happens after the transaction is committed. There is no way to rollback the update of the entity, and any database operation here will be performed with no active transaction (unless you begin one manually).
Example:
Module.Events.OnEntityModified.Subscribe(
procedure(Args: TEntityModifiedArgs)
begin
// code here
end
);
TEntityModifiedArgs Properties:
Name | Description |
---|---|
Entity: TObject | The entity which was modified. |
Handler: TXDataBaseRequestHandler | The XData request processor object. |
OnEntityDeleting Event
Occurs right before an entity delete. This event happens in the middle of a database transaction, right before the entity is about to be deleted in the database.
Example:
Module.Events.OnEntityDeleting.Subscribe(
procedure(Args: TEntityDeletingArgs)
begin
// code here
end
);
TEntityDeletingArgs Properties:
Name | Description |
---|---|
Entity: TObject | The entity being deleted. |
Handler: TXDataBaseRequestHandler | The XData request processor object. |
OnEntityDeleted Event
Occurs after an entity is deleted. Note that, unlike OnEntityDeleting event, this event happens after the transaction is committed. There is no way to rollback the deletion of the entity, and any database operation here will be performed with no active transaction (unless you begin one manually).
Example:
Module.Events.OnEntityDeleted.Subscribe(
procedure(Args: TEntityDeletedArgs)
begin
// code here
end
);
TEntityDeletedArgs Properties:
Name | Description |
---|---|
Entity: TObject | The entity which has been deleted. |
Handler: TXDataBaseRequestHandler | The XData request processor object. |
OnModuleException Event
Occurs when an unexpected exception is raised during server request processing. By default, when that happens XData will send a response to the client with the property HTTP status code (usually 500 but other codes might be provided as well) and a JSON response with details of the error (a JSON object with properties ErrorCode and ErrorMessage). You can use this event to change that behavior when a specific exception occurs.
Example:
Module.Events.OnModuleException.Subscribe(
procedure(Args: TModuleExceptionArgs)
begin
// code here, for example:
if Args.Exception is EInvalidJsonProperty then
Args.StatusCode := 400;
end
);
TModuleExceptionArgs Properties:
Name | Description |
---|---|
Exception: Exception | The Exception object raised while processing the requested. |
StatusCode: Integer | The HTTP status code to be returned to the client. You can change this property to tell XData to send a different status code. |
ErrorCode: string | The value of the ErrorCode property in the JSON response to be sent to the client. You can modify this value. |
ErrorMessage: string | The value of the ErrorMessage property in the JSON response to be sent to the client. You can modify this value. |
Action: TModuleExceptionAction | The action to be performed:TModuleExceptionAction = (SendError, RaiseException, Ignore) Default value is SendError which means XData will send the HTTP response to the client with the specified StatusCode and with a JSON response that includes ErrorCode and ErrorMessage. You can optionally use RaiseException, which means re-raising the original exception and let it propagate through the code. This gives an opportunity for some Sparkle middleware to catch the raise exception. If that doesn't happen, the exception will be handled by the Sparkle dispatcher. The third option is simply choose Ignore. Use this option if you want to send a custom HTTP response yourself. In this case XData will simply do nothing and finish processing request silently. |
OnManagerCreate Event
Occurs when a TObjectManager instance is internally created by XData during request processing. You can use this event to initialize settings in the object manager, or change some behavior. For example, you can use this event to enable filters.
Example:
Module.Events.OnManagerCreate.Subscribe(
procedure(Args: TManagerCreateArgs)
begin
// code here, for example:
Args.Manager.EnableFilter('Multitenant')
.SetParam('tenantId', 123);
end
);
TManagerCreateArgs Properties:
Name | Description |
---|---|
Manager: TObjectManager | The TObjectManager instance that has just been created by XData. |
Authentication Example using JSON Web Token (JWT)
Please refer to Authentication and Authorization guide for more information about how to secure your XData API.