Upload Files to FM 17 Data API with ruby

Hi,

similar to that i have to fill up a container field via data-api

request: POST
FileMaker-Version: 17.02.203

i send in the header:

Authorization: "Bearer #{@token}", 'Content-Type' => 'multipart/form-data', 'Accept' => 'multipart/form-data'

the body

-----------------------d7ec2d47f3d743b01a8ed2a43d1174bea9160742e6
Content-Disposition: form-data; name="upload"; filename="Untitled2.pdf"
Content-Type: application/octet-stream

%PDF-1.3
%���������
4 0 obj
<< /Length 5 0 R /Filter /FlateDecode >>
stream
xU�A�0����a���MwUijP��)� ��L�cH!/���'�qbX�c��Xql�p`���3^���qϨ��SO�Ӵ�[Be��6��C~�E����]��Ŗ��ʲ��F�i%4�Ie��R��gD��:JD��������T�u����au��5���ϟ>��8�
endstream
endobj
5 0 obj
...

and receipt the answer from FM

"{"messages":[{"message":"Upload payload must contain a part named 'upload'.","code":"960"}],"response":{}}"

This is the Screenshot from the docs, delivered by the FM-Server-Version, on my customer-server.

whats going wrong?

Thanks,
Christian

I tried an example and this is my CURL debug output:

POST /fmi/data/vLatest/databases/Contacts/layouts/Contact%20Details/records/1/containers/SomeContainer?modId=1 HTTP/1.1
Host: 192.168.2.138
Accept: */*
Authorization: Bearer c7eeaf65b1a7491e58813eef8ebe35d39035585736a0c66e949e
Content-Length: 122341
Content-Type: multipart/form-data; boundary=------------------------94aabc0f459d03fa

So content type from you doesn't have the boundary?

And here another upload with form data:

POST /fmi/data/vLatest/databases/Contacts/layouts/Contact%20Details/records/1/containers/SomeContainer?modId=1 HTTP/1.1
Host: 192.168.2.138
Accept: */*
Authorization: Bearer 3d1a0542fb800110fa17ae286134f38633792900bbeaf258e789
Content-Length: 200
Content-Type: multipart/form-data; boundary=------------------------75f1a90263c17a39

--------------------------75f1a90263c17a39
Content-Disposition: form-data; name="upload"; filename="Hello.txt"
Content-Type: text/plain

Hello World
--------------------------75f1a90263c17a39--

so make sure your code produces something similar.

Thanks Monkeybread, good point!
Now i changed the header Content-Type to:

"multipart/form-data; boundary=---------------------4fcec1fec5bc3be7fdaefdc869c9ff280d1968e1e8"

(same boundary like in body)

but ... same result

header Accept: changed to '*/*' => same result

Can you see what you send including header and body section?

2 Likes

Thanks Monkeybread!

I sent the post request to a different app and saw that the library i used Ruby/HTTParty didnt send the body because multipart is not supported.
I switched to Faraday and now it works well.

For the case it may help someone, here is the code

url = "https://rocky.datenbank-hosting.com/fmi/data/v1/databases/rocky/layouts/#{layout}/records/#{fm_id}/containers/#{container_field_name}/1"
 ur = URI.parse(url)
      conn = Faraday.new(url, headers: { authorization: "Bearer #{@token}" }) do |f|
        f.request :multipart
        f.request :url_encoded
        f.adapter :net_http
      end
      payload = { :upload => Faraday::UploadIO.new(file_path, 'image/jpeg') }
      response = conn.post(ur.path, payload)

I spent days with this!
Gems i tried that are not working for me:

  • FmRest (Beezwax) => could not create any record, and i found it more helpful to go more to the root-libraries
  • directly CURL inside ruby => that is too much root :slight_smile: possible, but at the end you want to have a wrapper, that is more convenient
  • Multipart-Post => workes fine, but not for FileMaker
  • and some others :slight_smile:
3 Likes

Great. I just used my MBS Xojo FMAPI Plugin in Xojo to try.