Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

VFP with RESTFUL 1

Status
Not open for further replies.

RoadRunnerOz

Programmer
Aug 22, 2000
128
AU
Hi:

I'm trying to send orders to a restful API using VFP7. I have done it before as the first example shows.

Example 1
lcUsername = ALLTRIM(sysfile.User)
lcPassword = ALLTRIM(sysfile.Pass)
lcAsync = .F.
lcFile = "XMLFileCreatedInTempDirectory"

oHTTP = CREATEOBJECT('MSXML2.XMLHTTP')
* - I want product 36073
lcUrl = "
oHTTP.OPEN("GET", m.lcUrl, m.lcAsyn, m.lcUsername, m.lcPassword)
oHTTP.setRequestHeader("Content-Type", "text/xml")
oHTTP.SEND(CREATEBINARY(m.lcFile))

IF "error" $ LOWER(.oHTTP.responseText) OR "we're sorry, but something went wrong" $ LOWER(.oHTTP.responseText)
=MESSAGEBOX("Order: " + m.lcOrderno + CHR(13) + .oHTTP.responseText)
ELSE
=MESSAGEBOX("Order: " + m.lcOrderno + CHR(13) + "Successfully Posted")
ENDIF

STORE .NULL. TO oHTTP
*-- end working code

Example 2

oHTTP = CREATEOBJECT('MSXML2.XMLHTTP')
lcAPIKey = ALLTRIM(sysfile.FFEAPIkey)
lcAsync = .F.
lcUrl = "
oHTTP.OPEN("POST", m.lcUrl, m.lcAsync, m.lcAPIKey)
oHTTP.SEND("")

oHTTP.ResponseText returns:
<?xml version="1.0" encoding="utf-8"?>
<FFEAuthentication>
<Status>Failed</Status>
</FFEAuthentication>

The documentation I got is poorly written, full of grammar/spelling mistakes, incorrect website, sometimes http other times https....
I asked for example code in any language for the various commands and got this for a response:
As for coding your request to the API I cannot help you more than the documentation provided, technically it is exactly the same as a webpage posting the string pairs listed in the API to the endpoint.
There is no mystery. Then the API will return XML

Not very helpful but my guess is he has no idea himself.

This is basically what I have to work with:
FFE Order API uses an http POST request and XML response message and can be run on any platform and in any programming language.
Every API request requires you to authenticate to the API. You will be allocated an API Key that links your business to the system.

Example:
This call is to check that the server is responding and the API key used is correct.

This call is to create an order:
etc...

Any ideas?

I have tried:

oHTTP = CREATEOBJECT('MSXML2.XMLHTTP')
lcAPIKey = ALLTRIM(sysfile.FFEAPIkey)
lcAsync = .F.
lcUrl = "
oHTTP.OPEN("POST", m.lcUrl, m.lcAsync, m.lcAPIKey)
oHTTP.SEND("")
I get OLE IDispatch exception code 0 from msxml3.dll: Access denied

and
lcUrl = "oHTTP.OPEN("POST", m.lcUrl + m.lcAPIKey, m.lcAsync, m.lcAPIKey)
oHTTP.SEND("")
I get OLE IDispatch exception code 0 from msxml3.dll: Access denied

and
lcUrl = " + m.lcAPIKey
oHTTP.OPEN("POST", m.lcUrl )
oHTTP.SEND("")

oHTTP.ResponseText returns:
<?xml version="1.0" encoding="utf-8"?>
<FFEAuthentication>
<Status>Failed</Status>
</FFEAuthentication>

and
oHTTP.OPEN("POST", m.lcUrl, .F. )
oHTTP.SEND("")

oHTTP.ResponseText returns:
<?xml version="1.0" encoding="utf-8"?>
<FFEAuthentication>
<Status>Failed</Status>
</FFEAuthentication>

I release oHTTP and create a new object between calls.

IF I paste + m.lcAPIKey in the command window of Firefox I get an OK

Any ideas?

Thanks in advance

Mick













Michael Ouellette
 
You focus too much on the parameters user/password of the open method of the httpxmlrequest.
As you say yourself the api key can be sent as get parameter, then simply add it to the URL.
In POST requests, this has to become part of the body you send.

I wrote about the user/pass here not long ago in thread184-1761921.
I still don't know what type of authentication the user/password parameters of the httpxmlrequest mean, but it's wrong to impose authentication to work through these parameters just because they exist. Do whatever you need to do. I can share your pain about bad documentations of APIs, but you can't say they implemented it wrong because it doesn't work with this specific MS implementation of some authentication method. Many authentication methods are even complexer and work within the get URL parameter or post body, as for example OAuth. I never used the user/pass parameters in any API.

The thing I said about the basic auth in thread184-1761921 is also no general way. If you have a clear specification of adding apikey as a get parameter, then do that. And then do a GET request.

Bye, Olaf.
 
Thanks Olaf.

That was quick.

I tried your code.

lcAPIKey = ALLTRIM(sysfile.FFEAPIkey)

o = CreateObject("msxml2.xmlhttp")
o.open("GET","
*-- don't have a username, only a password/apikey
lcBasicAuth = "Basic " + Chrtran(Strconv(m.lcAPIKey,13),"=","")
o.setRequestHeader("Authorization",lcBasicAuth)

o.send()

o.ResponseText returns the same error:
<?xml version="1.0" encoding="utf-8"?>
<FFEAuthentication>
<Status>Failed</Status>
</FFEAuthentication>

any more hints?

Mick


Michael Ouellette
 
Also tried:

lcAPIKey = ALLTRIM(sysfile.FFEAPIkey)
o = CreateObject("msxml2.xmlhttp")
o.open("GET","
In case I needed a user name
lcBasicAuth = "Basic " + Chrtran(Strconv(":"+lcAPIKey,13),"=","")

lcBasicAuth = lcAPIKey
o.setRequestHeader("Authorization",lcBasicAuth)

o.send()

same error.. Grrr

Michael Ouellette
 
>IF I paste + m.lcAPIKey in the command window of Firefox I get an OK

You said this works, then do it:
Code:
lcAPIKey = ALLTRIM(sysfile.FFEAPIkey)
o = CreateObject("msxml2.xmlhttp")
o.open("GET","[URL unfurl="true"]https://www.website.com/cgi-bin/newapi.cgi?apikey="+lcAPIKey)[/URL]
o.send()

All I said is that a) user/pass are not parameters to use for basic authentication and b) they do some unknown authentication, you should NOT focus on them, simply ignore them.
I never said you should use basic authentication to pass in the API key. That Basic authentication header is doing the same as and that's not the syntax asked of you to pass in the api key, is it? So it can't work that way.

As long as you're not more specific we can't help you, I can only tell you what does NOT work and help you to look into other possibilities. Stop trying a route, that doesn't work, stop banging your head against a wall. That's what I was saying on the one side.

And on the other side I said twice you just have to make the GET call that you found out works. Why don't you simply make it? What is hindering you to put the URL working in a browser into the open method?


myself said:
As you say yourself the api key can be sent as get parameter, then simply add it to the URL.
and
myself said:
If you have a clear specification of adding apikey as a get parameter, then do that. And then do a GET request.

You made a POST request, when a GET request worked. You might also be able to do a POST request, but
myself said:
In POST requests, this has to become part of the body you send.

Bye, Olaf.
 
Olaf:

That works!

I used POST simply because that is what the documentation implied ( I think )!
FFE Order API uses an http POST request and XML response message and can be run on any platform and in any programming language.

PS: I know absolutly nothing about Restful API's except that last time I had examples to work off albeit in another language I knew nothing about. That was easy.
PPS: You obviously know your stuff but I basically didn't understand a word you wrote, code I can read!

Now I wait because the webmaster still hasn't loaded any products for our company.
Thanks again!





Michael Ouellette
 
In a POST the apikey and other parameters would go into the body of the request, which you pass in with o.SEND(body)
There would most probably also be a header specifying the mime type of the body in that case. I can't tell you without reading the specs.

In the end you still found the solution yourself to go with a GET instead. It would only make a big difference, if the endpoint would be httpS, secure http, because then the body is transported encrypted, while the URL, the target request adress, is not. Otherwise both get and post parameters are passed unencrypted and so you openly send your API key anyway.

So if there is no https endpoint you don't take any further risc by using GET. But if there is a https endpoint you should use POST to not show your key to your ISP or anyone else being able to listen to and record the http communication.

You think: The API key is not much revealed, as you can get it for free (I assume so)? Well, the key can be used up to any rate limit and then you'd most probably have to pay for more. Also anything can be made on behalf of your app name.

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top