Hi Wagner,
sorry - did not see your answer earlier.
Ok - I understand so the RegisterServiceType is empty on purpose.
My Service Interface was declared as follows ...
[ServiceContract]
IMemexService = interface(IInvokable)
['{B395D718-0A27-4DEF-BEA9-AF556E291441}']
function InitSession(AnIP: String): String;
function IsValidSession(const AnIP: String; ASessionID: String): Boolean;
function Test: String;
end;
This is the declaration of the implementation class ...
[ServiceImplementation]
TMemexService = class(TInterfacedObject, IMemexService)
function InitSession(AnIP: String): String;
function IsValidSession(const AnIP: String; ASessionID: String): Boolean;
function Test: String;
end;
... with ...
function TMemexService.InitSession(AnIP: String): String;
var
s: TSession;
begin
s := TXDataOperationContext.Current.GetManager.Find<TSession>.Where
(TExpression.Eq('Ip', AnIP)).UniqueResult;
if Assigned(s) then
TXDataOperationContext.Current.GetManager.Remove(s);
s := TSession.Create;
s.Id := doubleguid;
s.Ip := AnIP;
TXDataOperationContext.Current.GetManager.Save(s);
Result := s.Id;
end;
function TMemexService.IsValidSession(const AnIP: String;
ASessionID: String): Boolean;
begin
Result := true;
end;
function TMemexService.Test: String;
begin
Result := 'Test';
end;
and
initialization
RegisterServiceType(TypeInfo(IMemexService));
I had overridden the On* delegates ... so this might have caused the problem that my service procedures did not work?
TctriXDataRequestHandler = class(TXDataRequestHandler)
private
procedure DoForbidden;
strict protected
procedure OnBeforeEntityMerge(Manager: TObjectManager;
Entity: TObject); override;
procedure OnBeforeEntityUpdate(Manager: TObjectManager; AClass: TClass;
IdValue: Variant); override;
procedure OnBeforeEntityUpsert(Manager: TObjectManager; AClass: TClass;
IdValue: Variant); override;
procedure OnCollectionRetrieve(Manager: TObjectManager; Entity: TObject;
Collection: IObjectList); override;
procedure OnEntityCreate(Manager: TObjectManager; Entity: TObject);
override;
procedure OnEntityDelete(Manager: TObjectManager; AClass: TClass;
IdValue: Variant); override;
procedure OnEntityMerge(Manager: TObjectManager; Entity: TObject); override;
procedure OnEntityRetrieve(Manager: TObjectManager;
Entity: TObject); override;
procedure OnEntitySetRetrieve(Manager: TObjectManager;
Criteria: TCriteria); override;
procedure OnEntityUpdate(Manager: TObjectManager; Entity: TObject);
override;
procedure OnEntityUpsert(Manager: TObjectManager; Entity: TObject);
override;
procedure OnPrimitivePropertyRetrieve(Manager: TObjectManager;
Entity: TObject; Prop: TXDataSimpleProperty); override;
procedure OnStreamPropertyRetrieve(Manager: TObjectManager; Entity: TObject;
Prop: TXDataSimpleProperty); override;
procedure OnStreamPropertyUpdate(Manager: TObjectManager; Entity: TObject;
Prop: TXDataSimpleProperty; var Blob: TBlob); override;
procedure OnValueRetrieve(Manager: TObjectManager; Entity: TObject;
Prop: TXDataSimpleProperty; var Value: TValue); override;
end;
... with ...
procedure TctriXDataRequestHandler.OnEntityUpsert(Manager: TObjectManager;
Entity: TObject);
begin
DoForbidden;
end;
and so on for the other OnXY-events,
Besides of the service operations - which I could not get to work in the example above - my problem with XData - even though I would really like to use it - is, that I do not know how to implement authorization beyond Username-Password and grant all access or deny all access by that means. So at the moment I could only see good use for it in private api settings not in public api once. Either I am missing something or the way to deal with authorizations/authentifications and the missing capabilities of customization of the exportet standard REST interface are still improvable.
But do not understand this to be a harsh criticism - overall it is an amazing product - and all I mention here is IMO just a problem if you want to share an XDATA-based API with third parties beyond your organization or if you want to leverage it in a public website without developing an intermediary service.
At the moment - until XData might support what I need in this situation - I achieve what I want using Sparkle with a Connection Pool according to this article http://edn.embarcadero.com/article/30027 .
I first tried to use the ConnectionPool of your source - but was not successful because I wanted to access a whole datamodule with firedac components from within each threaded module instance. This would not have been possible - as far as I did see it. Would it? It would be cool if
TDBConnectionFactory could be given a datamodule type and IDBConnectionPool could give me not only a connection, but also a whole datamodule instance in that case. But I am not sure if that would be possible.
Well for me it works at the moment with the approach shown in the Jensen tutorial and I really like the minimalism and performance Sparkle offers me. IMO it is the best component set for microrservice development with Delphi. Thanks to you guys..