I need to use a Soap API and expose it as REST.
Something just like the Weather API discussed in this Apigee tutorial/doc
http://docs.apigee.com/tutorials/proxy-soap-service
However, in my case, instead of using a rest GET, I have to use a rest POST with the parameters in a json payload.
So instead of doing this
GET http://myapi.apigee.net/weatherrest/cityweatherbyzip?ZIP=07030
I need to do this:
POST http://myapi.apigee.net/weatherrest/cityweatherbyzip
{
"ZIP":07030
}
with apigee taking the parameter from the posted json payload and making the normal SOAP call with it.
At the moment, it doesn't seem to work, the call reaches the target but without the parameter. It returns:
{
"GetCityWeatherByZIPResponse":{
"GetCityWeatherByZIPResult":{
"Success":"false",
"ResponseText":"Invalid ZIP",
"State":{
},
"City":{
},
"WeatherStationCity":{
},
"WeatherID":-1,
"Description":{
},
"Temperature":{
},
"RelativeHumidity":{
},
"Wind":{
},
"Pressure":{
},
"Visibility":{
},
"WindChill":{
},
"Remarks":{
}
}
}
}
What should i do to make sure parameters are taken from my json payload and propagated to the SOAP target call? Many Thanks
Actually, this is all related to those ExtractVariable block.
See this:
http://docs.apigee.com/api-services/reference/extract-variables-policy
So in this case, something like this should be used:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExtractVariables async="false" continueOnError="true" enabled="true" name="GetCityWeatherByZIP-extract-form-param">
<DisplayName>GetCityWeatherByZIP Extract Form Param</DisplayName>
<Source clearPayload="true|false">request</Source>
<JSONPayload>
<Variable name="ZIP" type="string">
<JSONPath>$.ZIP</JSONPath>
</Variable>
</JSONPayload>
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
</ExtractVariables>
in Api > Develop > policy
(the one corresponding to the first step of your PUT)
Related
I am trying to upload a text file to OneDrive using Graph APIs and I also want to update it in the same request using JSON batch.
My JSON request body is below:
{
"requests":[
{
"id":"1",
"method":"PUT",
"url":"/drives/b!ddubdQaackeT9nu3x4onivgPxHH2-
gpFsk_mo9hryZabqK7w279YSpMqiNodZDaa/items/01BTTSDZ56Y2GOVW772
5BZO354PWSELRRZ:/abc2.txt:/content",
"headers":{
"Content-Type":"application/octet-stream",
"Content-Length":"21"
},
"body":{
"content":"Test content for body"
}
},
{
"id":"2",
"method":"PATCH",
"url":"/drives/b!ddubdQaackeT9nu3x4onivgPxHH2-
gpFsk_mo9hryZabqK7w279YSpMqiNodZDaa/items/01BTTSDZ56Y
2GOVW7725BZO354PWSELRRZ:/abc2.txt",
"headers":{
"Content-Type":"application/json; charset=utf-8"
},
"body":{
"fileSystemInfo":{
"lastModifiedDateTime":"2020-08-09T00:49:37.7758742+03:00"
}
},
"dependsOn":["1"]
}
]
}
When I send this request from my code, I always get a response "Invalid body for request id: 1. The body must be a valid base64 string or JSON.".
Postman refused to run the above request with the message "Method not allowed".
In the above example, I am uploading and updating text files but my code will have to handle all file types (e.g. images, videos, etc.)
Not sure if I am correctly specifying all the JSON fields. Unfortunately unable to find much info on this. Any help would be appreciated.
I'm just doing the preparation for an integration with EasyPost's Shipping API, which will be server side C#, but we always build a PostMan collection for new integrations, so that we can test data separately from the application if there's an issue.
While I do love the fact that EP provide C# libraries and examples, I'm struggling to find anything that just gives me a list of required headers and the raw JSON format for the body of any requests. It feels a bit like they're just being a little too helpful.
I'll be looking at the Orders endpoint probably.
I've got an account, I've checked all their documentation and searched the internet but haven't found anything so I'm hoping I'm not the first developer to want to use a client application for testing outside my code.
Update:
EasyPost now does have a public workspace https://www.postman.com/easypost-api
with at least 1 public collection
The curl examples are basically the same as json:
For the Address creation example:
-d "address[street1]=417 MONTGOMERY ST"
is the equivalent of
{ "address": { "street1": "417 MONTGOMERY ST" } }
(you might have to escape some characters to be valid json).
Check out How to stimulate cURL request to a request using postman for postman with HTTP Basic Auth.
EasyPost does not provide a public Postman collection; however, here is an example of a shipment Postman body (raw) that could be used. You can adjust the values, actions, objects, etc to your needs.
Using the following, you shouldn't need to pass any headers. You'll pass your API key under the username field with the Basic Auth authorization type.
{
"shipment": {
"to_address": {
"id": "adr_123..."
},
"from_address": {
"id": "adr_123..."
},
"parcel": {
"id": "prcl_123..."
},
"carrier_accounts": {
"id": "ca_123..."
},
"options": {
"address_validation_level": "0"
}
},
"format": "json",
"controller": "shipments",
"action": "create"
}
Have the following XML as a result of the HTTP GET function from the B2B supplier.
<Invoices xmlns="http://gateway.com/schemas/Invoices" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://gateway..com/schemas/Invoices Invoices.xsd">
<DocumentInfo>
<DocType>INVOICES</DocType>
<DocVersion>2.0</DocVersion>
</DocumentInfo>
<Header>
<StartDate>2018-12-01T00:00:00+01:00</StartDate>
<EndDate>2019-01-03T00:00:00+01:00</EndDate>
</Header>
<Documents>
<Invoice InvoiceId="RP82807" InvoiceDate="2019-01-02T00:00:00+01:00" DocumentType="IN" RefDocId="FT34532" RefDocType="ORDER" SystemId="10" HasPDFImage="0" />
<Invoice InvoiceId="T609881" InvoiceDate="2018-12-31T00:00:00+01:00" DocumentType="IN" RefDocId="FT39339" RefDocType="ORDER" SystemId="0" HasPDFImage="0" />
</Documents>
</Invoices>
Based on this article I've created the liquid map file to get the list of InvoiceIds:
{
"Invoice": "{{content.Documents.Invoice}}"
}
When using it in the LogicApp in the XML->Json converter, got the following result:
{
"Invoice": ""
}
I have also tried this as a liquid file:
{
"Invoice": "{{content.Invoices.Documents}}"
}
and this:
{
"Invoice": "{{content.Invoices.Documents.Invoice}}"
}
with the same result.
Can you give me a tip what I do wrong?
I tried to transfer part of your xml file to json with this map:
{
"DocType":"{{content.DocumentInfo.DocType}}",
"Invoice":"{{content.Documents.Invoice}}"
}
And get the output:
{
"DocType": "INVOICES",
"Invoice": ""
}
So this means I can get the DocType but can't get Invoice properties, so I think maybe the Liquid map doesn't support the XML format. Maybe you could change it to like this:
<Invoice>
<InvoiceId>T609881</InvoiceId>
<InvoiceDate>2018-12-31T00:00:00+01:00</InvoiceDate>
<DocumentType>IN</DocumentType>
<RefDocId>FT39339</RefDocId>
</Invoice>
This will work, or you could go to Liquid reference to check is there any methods to match the properties.
Note:what you want for now,binding to Xml Attributes is not currently supported.You could refer to this answer.
If you still have other questions, please let me know.
UPDATE:You still could do it with logic app. For example I used a FTP connector to get xml file content then create a json with "json(xml(body('Get_file_content')))" expression.
And this is the result.
I have a JSON request for my API it takes input string as a pattern ${some.input} which is equivalent to SoapUI properties expansion
request.json looks like:
{
"config": {
"logmsg": "${some.input}",
"logfile": "kilores.log",
"loglevel": "${#TestCase#api_name}"
}
}
when I send an sopaui request the raw looks like
{
"config": {
"logmsg": "",
"logfile": "kilores.log",
"loglevel": "info"
}
}
The issue here is that SoapUI assumes ${some.input} belongs to SoapUI properties expansion and needs to be evaluated. Actually ${some.input} is part of the API JSON request and should not get evaluated by SoapUI before sending it. How can I achieve this? I have other SoapUI variables (like ${#TestCase#api_name}) in the same request that must be evaluated but not that particular one that belongs to the actual request.
I believe it is little trivial one. As you pointed correctly, it was being treated by soapui as property expansion and that is the reason it is being sent as "logmsg" : ""
All you need to do is add an additional $. Hence your request should be as shown below:
{
"config": {
"logmsg": "$${some.input}",
"logfile": "kilores.log",
"loglevel": "${#TestCase#api_name}"
}
}
I'm having trouble properly formatting one particular soap parameter using the node-soap module for node.js as a client, to a 3rd-party SOAP service.
The client.describe() for this method says this particular input should be in the shape of:
params: { 'param[]': {} }
I have tried a bunch of different JSON notations to try to fit my data to that shape.
Examples of formats that do NOT work:
"params": { "param": [ {"myParameterName": "myParameterValue"} ] }
"params": [ "param": { "name": "myParameterName", "_": "myParameterValue"} ]
"params": { "param" : [ {"name": "myParameterName", "_": "myParameterValue"} ] }
"params": { "param[]": {"myParameterName": "myParameterValue" } }
"params": { "param[myParameterName]": {"_": "myParameterValue" } }
I must be overlooking something, and I suspect I'm going to feel like Captain Obvious when some nice person points out what I'm doing wrong.
Here is what DOES work, using other soap clients, and how they handle the "named parameter with a value"
soapUI for this method successfully accepts this particular input via XML in the shape of:
<ns:params>
<ns:param name="myParameterName">myParameterValue</ns:param>
</ns:params>
Also, using PHP, I can successfully make the call by creating a stdClass of arrays like so:
$parms = new stdClass;
$parms->param = array(
array(
"name"=>"myParameterName","_"=>"myParameterValue"
)
);
and then eventually passing
'params' => $parms
to the PHP soap client
Many thanks!
To get a better look at what XML was being generated by node-soap, I added a console.log(message) statement to the node_modules/soap/lib/client.js after the object-to-XML encoding. I then began experimenting with various JSON structures to figure out empirically how they were mapping to XML structures.
I found a JSON structure for node-soap to generate the XML in my 3rd-party's required named-parameter-with-value format. I was completely unaware of the "$value" special keyword. Looks like this may have been added in the 0.4.6 release from mid-June 2014. See the change history
"params": [
{
"param": {
"attributes": {
"name": "myParameterName"
},
$value: "myParameterValue"
}
}
]
(note the outer array, which gives me the luxury of specifying multiple "param" entries, which is sometimes needed by this particular 3rd-party API)
generates this XML:
<tns:params>
<tns:param name="myParameterName">myParameterValue</tns:param>
</tns:params>
which perfectly matches the structure in soapUI (which I already knew worked) of:
<ns:params>
<ns:param name="myParameterName">myParameterValue</ns:param>
</ns:params>