RTC Forums
April 23, 2024, 07:09:08 AM *
Welcome, Guest. Please login or register.

Login with username, password and session length
 
   Home   Help Login Register  
Pages: [1]
  Print  
Author Topic: Well written REST server  (Read 3725 times)
ClementDoss
RTC License
***
Posts: 36


« on: November 10, 2019, 09:31:07 PM »

Hi,

I'm revisiting my RESTServer using only the server side components you will continue to provide/support. (I will miss LoadBalancer. But there's a way to replace it.)
I want to be sure I use the right components as they should.
I reduced my server to a few rtcHTTPServer and a lot of rtcDataProvider.
I replaced client side components and removed remote functions. 

I want to keep the excellent performance I have today, but using only the components you will support.
For example: I have the Authorization dataProvider that will handle authorization method and connect to a database to check user and password.
Another dataProvider to handle Synchronous and Asynchronous requests. My Sync request would take at most 2s to complete (database queries).
My Async request will spawn a thread, and return immediately.

Here are a few code examples.
I create one of the servers as shown below
Code:
   fWebAPIServer  := TRtcHttpServer.New;
   fWebAPIServer.Name := 'webAPIserver';
   fWebAPIServer.Tag := 0;

   fWebAPIServer.MultiThreaded  := True;
   fWebAPIServer.Blocking       := False;
   fWebAPIServer.RestartOn.ListenLost := True;

   fWebAPIServer.OnListenStart  := event_WebAPIServer_OnListenStart;
   fWebAPIServer.OnListenStop   := event_WebAPIServer_OnListenStop;
   fWebAPIServer.OnListenLost   := event_WebAPIServer_OnListenLost;
   fWebAPIServer.OnListenError  := event_WebAPIServer_OnListenError;

My login DataProvider looks like this:
Code:
procedure TWSWebLoginAPIHandler.DoEvent_CheckRequest(aSender: TRtcConnection);
var
  lUserSession : TcoreWebServerWebSession;
  lData : TRtcDataServer;
  lAuthRequest,
  lPassword : String;
  lMainSQLConnection : IcoreSQLConnection; // Usado para buscar usuario e senha!
  lAuthorized : Boolean;
begin
  lData := TRtcDataServer(aSender);
  lAuthorized := lData.FindSession( lData.Request.Cookie['session']);
  if not lAuthorized then
  begin
     // verificação de credenciais.
     // Temos que diferencar entre credenciais do internas e externas.
     lUserSession := TcoreWebServerWebSession.Create;
     lAuthRequest := lData.Request['Authorization'];
     fAuthorization.ParseAuthRequest( lAuthRequest,
                                      lUserSession.Authentication.&Type,
                                      lUserSession.Authentication.AuthUserName,
                                      lUserSession.Authentication.AuthCode,
                                      lUserSession.Authentication.AuthPassword,
                                      lUserSession.Authentication.AuthToken );

     lMainSQLConnection := glbSQLConnectionFactoryManager.MainConnection.AcquireConnection;
     lMainSQLConnection.GetLoginPassword( lUserSession.Authentication.AuthUserName,
                                          lUserSession.Authentication.AuthCode,
                                          lUserSession.Authentication.AuthUserID,
                                          lPassword );
     lAuthorized := DoCheckAuthorization( lUserSession.Authentication.&Type,
                                          lUserSession.Authentication.AuthUserName,
                                          lUserSession.Authentication.AuthCode,
                                          lUserSession.Authentication.AuthPassword,
                                          lUserSession.Authentication.AuthToken,
                                          lPassword);
     if lAuthorized then begin
        lData.OpenSession;
        lData.Response.Cookie['session'] := lData.Session.ID;
        lData.Session.asObj['sessiondata'] := lUserSession;
        lData.Accept;
     end;

  end;

end;



Would this structure block requests in any way? I don't want to block incoming user requests while processing data. For example, one user might be downloading a large file while another is attempting to upload a few images.
Is this the correct way to work with those classes.
Would the above code be easier to migrate to v10?

Best regards,
Clément
Logged
D.Tkalcec (RTC)
Administrator
*****
Posts: 1881


« Reply #1 on: November 11, 2019, 08:24:40 AM »

I would NOT advise you to start re-designing your Project(s) in an attempt to "prepare" for the upcoming RTC SDK version, because we are working on a completely NEW component set, which is being designed from the ground up. Even though there will be some similarities between the new component set and the RTC SDK, the back-bone of the new component set will be completely different. And since we are still in the design and development phase of this new component set, many things are still undecided and/or will be changing before the first production version is ready, so ... any questions about "migration" from the RTC SDK to this new component set will have to wait.

Anyway ... the code you've posted only accepts requests, but I don't see anything for processing them and/or returning a response. Since the RTC SDK is event-driven and multi-threaded, the only place you may use the connection object on the Server is inside an event triggered by the RTC component. As long as you keep that in mind, you should be fine. But ... if you spawn a new thread and try to access the connection component from there, it won't work, or worse - it would work in some special scenario while debugging but wreak havoc when your Server goes live.
Logged
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!
Page created in 0.022 seconds with 16 queries.