Cannot get INSERT FROM URL headers to work

As with so many postings, POSTMAN works fine, but I cannot figure out how to get FMP to accept the URL parameters and I would appreciate some guidance.

As you can see on this site:

The expected CURL parameters are:

curl -s -X POST
-H "X-RosetteAPI-Key: your_api_key"
-H "Content-Type: application/json"
-H "Accept: application/json"
-H "Cache-Control: no-cache"
-d '{"content": "Por favor Señorita, says the man." }'
"https://api.rosette.com/rest/v1/language"

In FileMaker, I tried putting the test text right in the "-d" above, but that didn't work so I created a field for it.

My FileMaker URL Parameters are:

"--X POST " &
"--header "X-RosetteAPI-Key: 123456789"" &
"--header "Content-Type: application/json"" &
"--header "Accept: application/json"" &
"--header "Cache-Control: no-cache"" &
"--data " " & GetAsURLEncoded(Rosette Language::theJson)

But, I get this error back:

{"code":"badRequestFormat","message":"Unexpected character ('%' (code 37)): expected a valid value (JSON String, Number, Array, Object or token 'null', 'true' or 'false')\n at [Source: (org.apache.cxf.transport.http.AbstractHTTPDestination$1); line: 1, column: 3]","stack":null}

My form, for what it's worth, looks like this:

Can anyone see why FileMaker is failing? I've worked at this for hours now....

Thanks!

Blockquote
"--X POST " &
"--header "X-RosetteAPI-Key: 123456789"" &
"--header "Content-Type: application/json"" &
"--header "Accept: application/json"" &
"--header "Cache-Control: no-cache"" &
"--data " " & GetAsURLEncoded(Rosette Language::theJson)

  1. You need to add whitespace end of each line (or new line ¶) (""--header "X-RosetteAPI-Key: 123456789" " &)
  2. Add backslash \ before double quotes inside quoted text ("--header "Cache-Control: no-cache" " &...)
  3. Store data into variable before insert from url and read data from that variable ("--data @$post_data")

You can read more from fm help: Supported cURL options

EDIT: Ok you might had already backslashes because this editor strips those from the text

2 Likes

consider using a set of custom functions to help build your cURL syntax. It takes care of all the escaping etc

Also, you don't need to URL encode your json. Just stick the json in a variable and feed it in that way. If you don't want to use CFs to build the syntax then make that last line with the data:

"-d @$json"

Note that $json is hard-wired in the string, no concatenation. It's an odd syntax for FM but that's the way it is meant to work.

3 Likes

Brilliant! Thanks Wim....It works!!! :slight_smile:

Also consider this:

This script (like a function) takes parameters and does the entire work for you including the Insert from URL and then gives you back the response. . .
It handles every type of Insert from URL.

1 Like

Thank you! :nerd_face:

It's a wonder a utility like that wasn't in FileMaker to begin with. Setting CURL options is a dark art in FileMaker (still in 19) with ZERO help from the product itself -- you're literally on your own.

1 Like

But you can call up our friends, and you know, whenever one can, they’ll come running to help you again... Servers scripts schema and all, all you have to do is post, the soup is here with answers for you...

1 Like

the mind buckling challenge is something working in Postman within minutes but felt eons if ever within FM ..

1 Like

Yep. True dat! :nerd_face:

Most often, I will take the curl code from Postman or Insomnia, and put it in a field, and throw a quote on it. All the escaping is done. And I can just swap out what I need.

So either I can add the needed &, ", or whatever... or I'll just wrap the pieces I need in < > and use substitute. I find the latter much easier most of the time.

2 Likes

It's pretty simple once you get used to it, just copy the Postman cURL, remove the url, replace single with double quotes, remove trailing backslashes (\), and maybe "template-ify" it if you need to put dynamic data in the curl options. e.g.:

curl --location --request POST 'https://my-url.com/endpoint' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic MY_SUPER_SECRET_LOGIN_INFO' \
--data-raw '{
    "fmDataSource": [
        {
            "database": "EDS1",
            "username": "username",
            "password": "password"
        },
        {
            "database": "EDS2",
            "username": "username",
            "password": "password"
        }
    ]
}'

Becomes $curlTemplate:

--location
--request POST
--header "Content-Type: application/json"
--header "Authorization: Basic {{auth}}"
--data-raw @$data

Then just create $data and $auth in separate variables and substitute in auth:
Substitute ( $curlTemplate ; "{{auth}}" ; $auth )

No need to substitute $data because the @ does so automatically.

3 Likes

I guess that's a long-winded way of saying that, while cURL has some rough edges in FM, I actually think vanilla Insert From URL is a pretty fine interface.

1 Like

That workflow sounds like a great BBEDit "Text Factory" (where you create one or more text modifications to be applied with a single click).

1 Like

INSERT FROM URL is fine, but offers zero support in the CURL options. It should offer name:value pair pop-up support like POSTMAN, at a minimum, or something. Often you don't need any help, but other times it would be, well, helpful.

The zero help, brain dead, FMP CURL options is a sad implementation for a premium paid product, IMHO.

1 Like

Or since you are already in FileMaker, you can do it there also. All about preference.

I have a utilities file that does stuff like that. Throw the text into a filed and that’s it. Don’t even have to click a button.

1 Like

Yes!!!

I actually do have a little javascript that does this conversion and even converts the json body into JSONSetElement syntax and breaks the variables into separate steps.

But the repo is private because I wasn’t sure I wanted to get any support requests or anything. Maybe I’ll make it public and slap a big disclaimer “not maintained!” on it.

3 Likes

I had thought about writing a utility like that, but this brain-dead blank page (FMP's URL Options), issue ONLY happens in FileMaker. Other environments have good support for URL parameters.

For example, in Java., it's all object-based.

Just set 'em and it works!

// open URL
//----------------
URL url = new URL("<URL _TO_GO_TO");
conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);

// set headers...
//-----------------------
conn.setRequestMethod("POST");

conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Accept", "/");
conn.setRequestProperty("Cache-Control", "no-cache");
conn.setRequestProperty("some-API-Key", "1234566789");
.
.
.
(easy)

You would then use an inputstream to read data and an outputstream to write your POST data, etc.

No utility needed. :slight_smile:

1 Like

As mentioned before; it's already been solved by the collection of custom function that I linked to early in this thread. Solved many years ago...
It gives you all the type-ahead you want plus it saves you from having to guess what cURL options are supported.

2 Likes

Thanks, but I really don't want to worry about copying and maintaining a bunch of slow, difficult-to-debug CFs to do what should have been in-product (FMP) long ago. I don't think you will agree with that, but to each their own. To wit, I just created a generic "INSERT FROM URL" alternative in a micro-service. That's a much more powerful approach and is not FMP only.

Pass name:value pairs for headers in simple GET method. Even works from the browser. :slight_smile:

(FileMaker not required.)

Thanks.

There is nothing inherently slow about CFs. And there is nothing to debug about this particular set of CFs, they're just string builders.
And 'worry' about scaffolding a solution!? What kind of worry is that? There's scaffolding involved with pretty much every solution in any platform.

If it is not in the solution but provided as a - free and easy - component you'll refuse to use it? Strange. Sounds like "I will be inefficient and that'll teach you"

2 Likes