Forums

Find answers, ask questions, and connect with our
community all around the world.

Home Forum Omnis General Forum REST API Client – POST file

  • REST API Client – POST file

    Posted by Uwe Smidt on September 13, 2024 at 2:34 pm

    Dear $all,
    I have found valuable input in this thread (https://www.omnis.net/community/forums/forum/discussion/picture-upload-via-api/), but for my particular problem, I still have a missing link.

    I would like upload a file with the OMNIS REST API client to an REST API service of another app, but I keep getting ‘Internal Server Error’. The API endpoint does work, if I test it with Curl or Postman, I can upload the file.

    My Omnis code goes as follows:

    Calculate iHTTPMethod as kOW3httpMethodPost

    Calculate icContentType as 'multipart/form-data'

    Do iHeadersList.$clear()

    Do iHeadersList.$add("Authorization","Bearer 3288b990-703a-11ef-9b57-290f46ee5e30")

    Do iHeadersList.$add("Content-Type","multipart/form-data")

    Calculate iURI as con("https://api.ninox.com/v1/teams/EjnXhyYwG2hZYxX6A/databases/tz8mz96j4nt0/tables/A/records/1/files")

    Do loFileOps.$openfile('/Users/usmidt/Desktop/Aruba.png')

    Do loFileOps.$readfile(lbinContent)

    Do loFileOps.$closefile()

    Calculate lcFileBase64 as utf8tochar(bintobase64(lbinContent))

    Calculate iContentChar as con('data:image/png;base64,',lcFileBase64)

    Do iRestfulObj.$init(iURI,iHTTPMethod,iHeadersList,iContentChar) Returns lStatus

    Do iRestfulObj.$run() Returns lStatus

    My problem seems to be the way I setup the body parameter of the POST, iContentChar. The REST service expects ‘multipart/form-data’, but how do I build the iContentChar?

    PS: feel free to test against the API endpoint, it is just a trial app setup for this purpose, without real data or value.
    PPS: the working Curl command is

    curl --location 'https://api.ninox.com/v1/teams/EjnXhyYwG2hZYxX6A/databases/tz8mz96j4nt0/tables/A/records/1/files' \

    --header 'Authorization: Bearer 3288b990-703a-11ef-9b57-290f46ee5e30' \

    --header 'Content-Type: multipart/form-data' \

    --form 'Robby3=@"/Users/usmidt/Desktop/Robby3.jpg"'

    File Uploaded Successfully%

    Any help is greatly appreciated!!!!!

    Best regards
    Uwe

    Uwe Smidt replied 11 months, 1 week ago 3 Members · 7 Replies
  • 7 Replies
  • Andreas Pfeiffer

    Administrator
    September 13, 2024 at 2:40 pm

    Hi Uwe,

    I am not sure but could it be that the content-length is required in the header? You could use the Omnis len() function to find out the length.

    Best,

    Andreas

  • Uwe Smidt

    Member
    September 13, 2024 at 2:51 pm

    Hi Andreas,
    Thanx for your prompt response!

    I use Postman to test API calls, and while it has a nice GUI to put things together, it also ‘translates’ into various other languages, e.g. the actual HTTP message:

    POST /v1/teams/EjnXhyYwG2hZYxX6A/databases/tz8mz96j4nt0/tables/A/records/1/files HTTP/1.1

    Host: api.ninox.com

    Authorization: Bearer 3288b990-703a-11ef-9b57-290f46ee5e30

    Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

    Content-Length: 184

    ------WebKitFormBoundary7MA4YWxkTrZu0gW

    Content-Disposition: form-data; name="Robby3"; filename="Robby3.jpg"

    Content-Type: image/jpeg

    (data)

    ------WebKitFormBoundary7MA4YWxkTrZu0gW--

    And yes, there is a Header ‘Content-Length’, but I have no clue as to what length to measure (and 184 (bytes?) for a 4.3 MB file seems a bit misleading…

  • Andreas Pfeiffer

    Administrator
    September 13, 2024 at 2:52 pm

    calculate iLength as len(iContentChar)

    And then add this to the header

    Best,

    Andreas

    • Uwe Smidt

      Member
      September 13, 2024 at 3:00 pm

      Did it, but still ‘Internal Server error’..

      Calculate lcFileBase64 as utf8tochar(bintobase64(lbinContent))

      Calculate iContentChar as con('data:image/png;base64,',lcFileBase64)

      Do iHeadersList.$add("Content-Length",len(iContentChar))

      Do iRestfulObj.$init(iURI,iHTTPMethod,iHeadersList,iContentChar) Returns lStatus

  • Uwe Smidt

    Member
    September 13, 2024 at 3:08 pm

    I have the feeling that it has to do with the way I construct the body:

    
    

    Calculate iContentChar as con('data:image/png;base64,',lcFileBase64)

    I tried

    Calculate iContentChar as con('data:multipart/form-data;base64,',lcFileBase64)

    because of

    Do iHeadersList.$add("Content-Type","multipart/form-data")

  • Paul Mulroney Mulroney

    Member
    September 15, 2024 at 1:09 pm

    I’ll try this out in the morning. I suspect that your content needs to be defined as list of key/value pairs, so it will be something like

    do vlContent.$define(vsKey,vsValue)

    do vlContent.$add(‘Robby3’,<image data>)

    • Uwe Smidt

      Member
      September 15, 2024 at 10:45 pm

      I got it! I got it! 🤩🤩
      It took some RTFM, and before that, some detective work…

      I think on the lists.omnis-dev.com I read that you can turn on logging. My knowledge of the OW3 HTTP worker came the online docs: Extending Omnis – Chapter 1: Web services – I wasn’t aware that there was a much more detailed help in Chapter 7 – OW3 worker objects. And there, I did not only find out how to turn on logging, but more importantly the method $multipartaddfile.

      Now it only took some trial & error, but here is the code that works:

      Calculate iHTTPMethod as kOW3httpMethodPost

      Do iHeadersList.$clear()

      Do iHeadersList.$add("Authorization","Bearer 3288b990-703a-11ef-9b57-290f46ee5e30")

      Do iHeadersList.$add("Content-Type","multipart/form-data")

      Calculate iURI as con("https://api.ninox.com/v1/teams/EjnXhyYwG2hZYxX6A/databases/tz8mz96j4nt0/tables/A/records/1/files")

      Do loFileOps.$openfile('/Users/usmidt/Desktop/300_5369.jpg')

      Do loFileOps.$readfile(lbinContent)

      Do loFileOps.$closefile()

      #Do llPartHeaders.$define(lcPartHeaderName,lcPartHeaderValue) ## does not seem necessary

      #Do llPartHeaders.$add('Content-Type','image/jpg') ## does not seem necessary

      Do iRestfulObj.$protocollog.$assign(kOW3logBasic+kOW3logData)

      Do iRestfulObj.$multipartaddfile('300_5369',lbinContent,'300_5369.jpg') ## ,llPartHeaders) does not seem necessary

      Do iRestfulObj.$init(iURI,iHTTPMethod,iHeadersList,kOW3httpMultiPartFormData) Returns lStatus

      Do iRestfulObj.$run() Returns lStatus

      This may only be a small step for mankind, but it’s a giant leap for me😃!

      Thanks so much for everyone who helped me along the way!

Log in to reply.