1

I'm working on a DElphi FMX project where I make a lot of requests to a REST backend.

I'm using one TRESTClient, and are dynamically creting a TRESTRequest every time I ask for something, my plan is to make it multitreading to make the UI be more responsive.

I have made a function called DoRequest, that do the actual request, it looks like something this:

Function TFormMain.Dorequest(Meth:TRESTRequestmethod;Url,RequestBody:String; 
Var Respons: TCustomRESTResponse):Boolean;
Var
  par: TRESTRequestParameter;
  Req : TRESTRequest;
begin
  Req := TRESTRequest.Create(RESTClient);
  With Req do
  try
    if RequestBody<>'' then
    begin
      Params.Clear;
      par := Params.AddItem('body',RequestBody);
      par.ContentType := ctAPPLICATION_JSON;
      par.Kind := pkREQUESTBODY;
    end;
    Method   := Meth;
    Resource := Url;
    Execute;
    Respons  := Response;
    Result  := Respons.StatusCode In [200,201];
  finally
    Req.Free;  // <-Error here
  end;
end;

I call it like this:

procedure TFormUser.Button1Click(Sender: TObject);
Var
  Respons: TCustomRESTResponse;
begin
  If DoRequest(rmPOST,CreateUserUrl,JSON,Respons) then
    begin
      ShowMessage('User '+EdEmail.Text+' created');
      ModalResult := MrOk;
    end

However, I get an Acces Violation when freeing Req, my TRESTRequest.

I found out that it is because the TCustomRESTResponse Respons is just made a pointer to the memory where the Req.Response is placed, so freeing Req also destroys Respons.

My question is: How do I make a copy of Req.Response that lives after Req is freed?

I have tried Respons.Assign(Response), but it gives the rather strange error: "Cannot assign a TCustomRESTResponse to a TFormMain"

Am I doing this the wrong way, also keeping in mind that I would like the actual request to be in another tread?

Michael

1
  • You could make a separate record or class that holds the relevant information of the response. If possible, I would deserialize/parse or pre-process the response contents as well, to translate it from raw information to useful information, before returning it. That way, the rest of the application won't depend on this specific TRestResponse, or even the fact that this information was fetched using REST. Commented Feb 23, 2018 at 8:28

1 Answer 1

1

When you don't link your own TRESTResponse to the client, the client will create one of its own and also free it. If you create your own TRESTResponse and assign it, the client will leave it alone, and you can free it whenever you want.

That said, like I mentioned in the comment, I think it's probably better to let the thread deal with deserializing the response, and have it pass a more generic class or record holding the relevant information (a value object, if you're into that), rather than passing around the specific TRESTResponse.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.