Show/Hide Toolbars

TMS XData Documentation

Navigation: Service Operations

TXDataOperationContext

Scroll Prev Top Next More

To help you implement your service operations, XData provides you some information under the context of the operation being executed. Such information is provided in a TXDataOperationContext object (declared in unit XData.Server.Module). The simplified declaration of such object is as followed.

 

TXDataOperationContext = class
public
  class function Current: TXDataOperationContext;
  function GetConnectionPool: IDBConnectionPool;
  function GetManager: TObjectManager;

  function Request: THttpServerRequest;
  function Response: THttpServerResponse;

end;

 

To retrieve the current instance of the context, use the class function Current.

 

Context := TXDataOperationContext.Current.GetManager;

 

Then you can use the context to retrieve useful info, like a ready-to-use, in-context TObjectManager to manipulate Aurelius entities (using the GetManager function) or the connection pool in case you want to acquire a database connection and use it directly (using GetConnectionPool method).

 

This way your service implementation doesn't need to worry about how to connect to the database or even to create a TObjectManager with proper configuration and destroy it at the end of process. All is being handled by XData and the context object. Another interesting thing is that when you use the TObjectManager provided by the context object, it makes it easier to manage memory (destruction) of entity objects manipulated by the server, since it can tell what objects will be destroyed automatically by the manager and what objects need to be destroyed manually. See Memory Management topic for more information.

 

The example is an example of an operation implementation that uses context manager to retrieve payments from the database.

 

uses 
  {...}
  XData.Server.Module;
 
function TCustomerService.FindOverduePayments(CustomerId: integer): TList<TPayment>;
begin
  Result := TXDataOperationContext.Current.GetManager.Find<TPayment>
    .CreateAlias('Customer''c')
    .Where(TLinq.Eq('c.Id', CustomerId) and TLinq.LowerThan('DueDate', Now))
    .List;
end;

 

Note that the database connection to be used will be the one provided when you created the TXDataServerModule. This allows you keep your business logic separated from database connection. You can even have several modules in your server pointing to different databases, using the same service implementations.

 

Inspecting request and customizing response

 

The context also provides you with the request and response objects provided by the TMS Sparkle framework.

You can, for example, set the content-type of a stream binary response:

 

function TMyService.GetPdfReport: TStream;
begin
  TXDataOperationContext.Current.Response.Headers.SetValue('content-type''application/pdf');
  Result := InternalGetMyPdfReport;
end;

 

Or you can check for a specific header in the request to build some custom authentication system:

 

function TMyService.GetAppointment(const Id: integer): TVetAppointment;
var
  AuthHeaderValue: string;
begin
  AuthHeaderValue := TXDataOperationContext.Current.Request.Headers.Get('custom-auth');
  if not CheckAuthorized(AuthHeaderValue) then
    raise EXDataHttpException.Create(401'Unauthorized'); // unauthorized
 
  // Proceed to normal request processing.
  Result := TXDataOperationContext.Current.GetManager.Find<TVetAppointment>(Id);
end;