misc_bb 7 Posted May 12, 2022 (edited) 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 May 12, 2022 by misc_bb Share this post Link to post
Mohammed Nasman 11 Posted May 12, 2022 (edited) 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: Edited May 12, 2022 by Mohammed Nasman Share this post Link to post
TiGü 21 Posted May 12, 2022 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
misc_bb 7 Posted May 12, 2022 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. Thank you. Share this post Link to post
misc_bb 7 Posted May 13, 2022 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
misc_bb 7 Posted May 16, 2022 (edited) 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 May 17, 2022 by misc_bb 1 Share this post Link to post