Jump to content
Mike_Lob

Enforce required attributes +Firedac Datamodule

Recommended Posts

Posted (edited)

Hi,

 

First of all: Thank you for providing us with this wonderuful implentation of your Rest library Andrea. I'm converting my own API servers to work with your library since it's far more enhanced than mine.

This being said .. 

 

1. How can I enforce Attributes provided with GET or POST calls?

I have read somewhere in your GIThub that it should be possible but I have yet to figure out how to do this.

 

2. How to dynamically change your database for a user.

 We have a Microsoft SQL server with a seperate database for every client.

 We also have one common database where we need to validate credentials and it will return the databasename from the sql server.

 For example: A user authenticates with an API key that we provied to the customer. That API key is linked to the users database and the SQL server returns that database name where we have to connect to - to perform specific user database queries.

I have adjusted the authentication method to accept an API key:

function TTokenResource.Authenticate(const AApiKey: string): Boolean;
var
  tmpFound : boolean;
begin
  DataModule1.FDQuery1.SQL.Text := 'select * from snippetexample';
  Datamodule1.FDQuery1.Open();
  Result := DataModule1.FDQuery1.RecordCount > 1;
  Result := false;

  //Result := true;
end;

Once authenticated we should open a database connection and start executing the users request and return a corresponding JSON. I have created a DATAmodule where my connection and query lives.

 

I found that you can use a FIREDAC context : [Context] FD: TMARSFireDAC;

But I cant figure out the right way to manipulate database connections for users, I could manually set users databases like so:

  FD.Connection.Params.DriverID := 'MSSQL';
  FD.Connection.Params.Database := '...';
  FD.Connection.Params.Server = 'ERROR';

But I feel this should not be done like this. Also the .Server param doesnt exist in this context.

Please forgive me if you see any 'newbie' questions. I start learning Delphi 4 months ago and I have yet to discover all Delphi concepts...

 

Thanks again for this awsome library!!

 

If anything is unclear please let me know.

Thanks for your time

Edited by Mike_Lob

Share this post


Link to post
On 7/25/2019 at 11:08 AM, Mike_Lob said:

Hi,

First of all: Thank you for providing us with this wonderuful implentation of your Rest library Andrea. I'm converting my own API servers to work with your library since it's far more enhanced than mine.

 

Hi, thanks for the kind words and sorry for the delay.

 

On 7/25/2019 at 11:08 AM, Mike_Lob said:

1. How can I enforce Attributes provided with GET or POST calls?

I have read somewhere in your GIThub that it should be possible but I have yet to figure out how to do this.

I guess you are referring to QueryParam like "sort" in http://localhost:8080/rest/default/query/EMPLOYEE?sort=LAST_NAME

You can use the Required attribute to let MARS check for the parameter's existence before calling the REST method.

 

    function GetDataset([QueryParam, Required] sort: string): TFDQuery;

 

On 7/25/2019 at 11:08 AM, Mike_Lob said:

2. How to dynamically change your database for a user.

 We have a Microsoft SQL server with a seperate database for every client.

 We also have one common database where we need to validate credentials and it will return the databasename from the sql server.

 For example: A user authenticates with an API key that we provied to the customer. That API key is linked to the users database and the SQL server returns that database name where we have to connect to - to perform specific user database queries.

<SNIP>

But I feel this should not be done like this. Also the .Server param doesnt exist in this context.

Please forgive me if you see any 'newbie' questions. I start learning Delphi 4 months ago and I have yet to discover all Delphi concepts...

 

I would add a specific value in the user's token, indicating the DB to use. You'll set this value in the token at authentication time (via API key or regular login).

You can see this thread for a similar approach: 

 

Keep in mind that your situation (if you store the connection name to be used inside the user's token) it's easier as you can use a connection name like 'TOKEN_CLAIM_DBCONNECTION':

 

[Context, Connection('TOKEN_CLAIM_DBCONNECTION', True)] FD: TMARSFireDAC;

 

And MARS will expand that connection name to the value of the DBCONNECTION name stored in the Claims of your (JWT) token.

 

If you need some fallback mechanisms or more dynamic behavior, follow the instructions in the "FireDAC Connections" thread I linked here above.

 

Feel free to ask whatever you need, sorry for the delay in this reply but I am abroad with family (vacation time).

 

Sincerely,

Andrea

 

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×