Jump to content
misc_bb

Delphi REST with PDF files

Recommended Posts

Hello, I'm currently implementing a tool to handle an API using Delphi REST components. The API we are dealing with returns a PDF file. Can Delphi handle REST this file type? I don't see any file type/content type option in the object inspector. I've made some testing it doesn't seem to replicate what I have in Postman.

 

Anyone have tried using Delphi REST with a PDF file as response? I just want to know otherwise I'll shift to Python.

 

Thanks in advance.

Edited by misc_bb

Share this post


Link to post

I don't know about Delphi Rest, but for the restful API, I use the excellent open source Delphi MVC framework.

 

you return the pdf as:

image.thumb.png.18d4ea86102abbf9b91a242f7a7bd0dd.png

Edited by Mohammed Nasman

Share this post


Link to post
unit REST.Types // Delphi 10.4

...

type //at line 123
  /// <summary>
  /// Content
  /// </summary>
  TRESTContentType = (ctNone, ctAPPLICATION_ATOM_XML, ctAPPLICATION_ECMASCRIPT, ctAPPLICATION_EDI_X12,
    ctAPPLICATION_EDIFACT, ctAPPLICATION_JSON, ctAPPLICATION_JAVASCRIPT, ctAPPLICATION_OCTET_STREAM, ctAPPLICATION_OGG,
    ctAPPLICATION_PDF,... // <-------

 

Share this post


Link to post

Thank you. I guess i'll just have to figure it out how to handle the return PDF file.

 

@Mohammed Nasman Yes, Delphi MVC is very good but I think it's too much for what I require. :classic_biggrin: Thank you.

Share this post


Link to post

In my testing I encounter this result:

{"Error":"Content type not recognized"}

 

Should I explicitly specify the return type in code? In Postman, there's no need for that but I'm not sure with Delphi REST. I've dealt with other APIs before but those are all text, json values and Delphi REST works perfectly.

Share this post


Link to post

After some trial and error again, was able to figure it out. This integration is with the Datylon API & Delphi REST components which handles a PDF return type. Although free account in Datylon doesn't work with this API integration. If anyone want to implements the API or something similar, the following code can be utilized. You just need to add some error handling.

 

Getauthorization - a function that return the Basic authentication with username and password 64bit encoded, small letter 'a' in 'authorization' is from datylon documentation

templateid and datasource - these are datylon parameters that needs be followed based on Datylon documentation

JSONStr - this is actually  the JSON string that needs to be sent

  TRY
    RESTRequest := TRESTRequest.create(nil);
    RESTRequest.Client := TRESTClient.create(RESTRequest);
    RESTRequest.SynchronizedEvents := False;

    RESTRequest.Client.UserAgent := DatylonUserAgent;
    RESTRequest.Client.FallbackCharsetEncoding := 'raw';
    RESTRequest.Client.BaseURL := datylon_BaseURI;
    RESTRequest.Client.ContentType := 'application/json';

    RESTRequest.Client.Params.AddItem('authorization', Getauthorization, TRESTRequestParameterkind.pkHTTPHEADER, [TRESTRequestParameterOption.poDoNotEncode]);
    RESTRequest.Client.Params.AddItem('x-graph-template-id', templateid, TRESTRequestParameterkind.pkHTTPHEADER, [TRESTRequestParameterOption.poDoNotEncode]);
    RESTRequest.Client.Params.AddItem('x-graph-datasource-name', datasource, TRESTRequestParameterkind.pkHTTPHEADER, [TRESTRequestParameterOption.poDoNotEncode]);
    RESTRequest.Body.ClearBody;
    RestRequest.body.Add(JSONStr, ctAPPLICATION_JSON);
//    RESTRequest.Resource := 'render';

    RESTRequest.Method := rmPOST;
    RESTRequest.Response := TRESTResponse.Create(RESTRequest);
    RESTRequest.Accept := 'application/pdf';
    RESTRequest.Execute;

    Codesite.Send('AuthenticationProcess Result: ' + RESTRequest.Response.Content);

    Result := RESTRequest.Response.RawBytes;

   finally
      RESTRequest.Free;
   end;

This code result will return rawbytes which you need to convert to a file. You need the FallbackCharsetEncoding to 'raw' - this I'm not sure but I've read this from here: https://community.embarcadero.com/de/component/easydiscuss/rest-request-error-to-get-pdf-attached-berlin-10-1?Itemid=1 I'm not even sure if it made a difference but I lost track of it which ones is working and which one is not when I was doing my trial and error. 🤣 the ultimate goal is to make it work haha

 

This is for the bytes to file conversion:

procedure TfrmMain.SaveBytesToFile(const Data: TBytes; const FileName: string);
var
  Stream: TFileStream;
begin
  Stream := TFileStream.Create(FileName, fmCreate);
  try
    if Data <> nil then
      Stream.WriteBuffer(Data[0], Length(Data));
  finally
    Stream.Free;
  end;
end;
//This will call the REST function above 

	RestResultFile := API.PDFProcess(LoadTextFromFile('text1.txt'));  //text file here contains the JSON string
    SaveBytesToFile(RestResultFile, 'test.pdf');

Thank you guys for your ideas. It led me to this solution above. Cheers!

Edited by misc_bb
  • Like 1

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

×