ColdFusion 10 REST API: How to parse JSON in body of payload - rest

I'm using ColdFusion 10's new build-in RESTful web services feature. When posting data, I'd like to send the payload as JSON in the body of the request. For example:
PUT https://mycompany.com/rest/v1.0/widget/261469 HTTP/1.1
Host: mycompany.com
Connection: keep-alive
Content-Length: 13
Content-Type: application/json
{"foo":"bar"}
Once this data is posted through the API, how should I parse and deserialize the JSON data on the server? Does ColdFusion REST service have a built-in way to do this? It seems that there is native support to deserialize "form" type (i.e. content-type application/x-www-form-urlencoded) by setting the restargsource attribute on cfargument to "form", but I'm not able to find any examples on how to deserialize JSON data natively. I was hoping for something like restargsource="json", but that doesn't exist. What is the recommended way to do this?

After a lot of research, it doesn't look like there's a native way for ColdFusion 10's REST API request handler to parse JSON requests automatically for us. We need to do this manually as follows:
<cfset var json = ToString(GetHttpRequestData().content) />
<cfif !IsJSON(json)>
<cfthrow errorCode="400" type="ArgumentException" message="#"Invalid JSON string: " & json#" />
</cfif>
<cfset var jsonObject = DeserializeJSON(json) />

You can also try
VARIABLES.postJSON = StructNew();
StructInsert(VARIABLES.postJSON, 'parameter1','xxx');
then user #SerializeJSON(VARIABLES.postJSON)#

Related

Prevent URL-encoding of values when adding headers to TRESTClient

I'm working on a Delphi REST client for a public API that requires an HMAC256/Base64 signed string to be added to the headers of the request to authenticate. I've spent hours trying to figure out why it's not working, so I compared the raw request from my Delphi client to that of a working C# library (using Wireshark).
It turns out my request matches perfectly the request generated by the working C# library, except that Delphi's REST client is URL-encoding the values added to the request's header, therefore invalidating the carefully crafted signature.
This is how I'm adding the signature string to the header:
RESTRequest1.Params.AddHeader('SIGNATURE', FSignature);
The signature string may have slashes, plus signs, and/or equal signs that are being URL-encoded when they shouldn't. For example when the value of the signature string is...
FSignature = '8A1BgACL9kB6P/kXuPdm99s05whfkrOUnEziEtU+0OY=';
...then the request should should output raw headers like...
GET /resource HTTP/1.1
User-Agent: Embarcadero URI Client/1.0
Connection: Keep-Alive
<snip>
SIGNATURE: 8A1BgACL9kB6P/kXuPdm99s05whfkrOUnEziEtU+0OY=
<snip>
...but instead Wireshark shows this as the real value being sent...
SIGNATURE: 8A1BgACL9kB6P%2FkXuPdm99s05whfkrOUnEziEtU%2B0OY%3D
Is there a way to prevent the URL-encoding of values when using AddHeader? Or maybe another way to add raw headers to a TRESTClient request?
PS: I already tried both TRESTRequest.Params.AddHeader and TRESTClient.AddParameter with TRESTRequestParameterKind.pkHTTPHEADER as the Kind parameter. Both resulted in URL-encoded values.
PS2: Using Delphi RAD Studio 10.3.
You should include poDoNotEncode in the Options property of the TRESTRequestParameter.
This can be done using:
RESTClient1.AddParameter('SIGNATURE', FSignature, pkHTTPHEADER, [poDoNotEncode]);
or by using:
RESTClient1.Params.AddHeader('SIGNATURE', FSignature).Options := [poDoNotEncode];

What is a working minimal example of POST /channelgroups/_bulkUpdate in Mirth REST API?

In the Mirth REST API found on EG https://localhost:8443/api/, under Channel Groups, there's a test section for bulkUpdate, which has two parameters: channelGroups, and removedChannelGroupIds. By default I set override to true.
Despite passing channelGroups and the ID list in various formats (EG as a channelGroup XML object, list of channels, list of channelGroups etc) Mirth rejects those formats and I have no idea what format Mirth is after. Leaving either field blank also fails. Does anyone have an example of a minimal working dataset for both fields that will return success from Mirth when calling bulkUpdate?
Mirth version is 3.6.0, but ideally it should also work in 3.5.1 for legacy devices.
This was answered on the user forum https://www.mirthcorp.com/community/forums/showthread.php?t=218606
That route actually expects multipart/form-data. So for example you could send a request with "Content-Type: multipart/form-data; boundary=abc123" and a payload like:
--abc123
Content-Type: application/xml; charset=utf8
Content-Disposition: form-data; name="channelGroups"
<set>
<channelGroup version="3.6.1">
<id>56a61dfb-58df-4286-8100-5ccab05364ba</id>
<name>Group 1</name>
<revision>1</revision>
<lastModified>
<time>1537550138646</time>
<timezone>UTC</timezone>
</lastModified>
<description></description>
<channels/>
</channelGroup>
</set>
--abc123
Content-Type: application/xml; charset=utf8
Content-Disposition: form-data; name="removedChannelGroupIds"
<set/>
--abc123--
As of mirth 3.6, it is not possible to call this API function from the SwaggerUI.
It also seems to be failing to create the channels within the channel group.

How to create a SOAP message from JSON payload in mule

I need to transform the following json payload into a soap message and send the message to a consumer, the consumer edits the data and sends back the soap message.
I haven't done much in soap. I only have REST experience. what steps do I need to take in a process like this?
what is the best approach?
[{"salesOrderId":"00004-5-6","saleName":"House Sale","status":"processing"}, {"salesOrderId":"00001-2-3","saleName":"Car Sale","status":"processing"}]
There are various way to perform this transformation, for example:
PATH - 1
Json To XML (with transformer or string set payload)
Xml To SOAP Request using XSLT, transformer or string set payload.
Send SOAP Request sobre HTTP (POST / Content-type: applicacion/xml / soapAction)
PATH - 2
Json To SOAP Request using Groovy, XSLT or string set payload.
Send SOAP Request sobre HTTP-OUTBOUND (POST / Content-type: applicacion/xml / soapAction)
PATH - 3
Json To SOAP Request Proxy (WSDL To Java).
Send SOAP Request sobre HTTP-OUTBOUND (POST / Content-type: applicacion/xml / soapAction)
The easiest way of doing it is extract the JSON elements from the JSON payload by using <json:json-to-object-transformer/>and store each node value in variables like flow variable in Mule.
Then You can create the SOAP request using XSLT and passing the flow variables value into XSLT as <mulexml:context-property/>
ref:- https://developer.mulesoft.com/docs/display/current/XSLT+Transformer
Once your SOAP XML is created, you can simply post them to your HTTP outbound endpoint pointing to your external web service you need to consume
Try using Mule DataMapper. That helps you to convert a JSON to XML in the more easier way. You can try it in Anypoint Studio of Mule.

Is there any resource that explains everything about the PUT, POST, DELETE operation in WCF Data Services?

Every single resource I'va come across on Internet always describes very well what you can do with the GET operation, how it works and so on, bu it never explains the POST/PUT/DELETE and particularly the format of the data you pass in the HTTP body (I'm using JSON). It always says "you can make a post request and pass the appropriate data in the body".
I am struggling with what I can do and not. For example I want to know if it is possible to update one field of one entry by just sending the updated value, and not the entire object.
Is there any document that explains clearly the possibilities and limitations?
Thanks a lot.
Easy to read documentation is here: http://www.odata.org/developers/protocols
If you want all the dirty details and a strict language you can read this document: http://msdn.microsoft.com/en-us/library/dd541188(PROT.10).aspx
You can modify a value of a single property by sending a PUT request.
For example if you send a GET to this URL:
http://services.odata.org/(S(kupqbta5wqnfz2cln1qk052x))/OData/OData.svc/Products(0)/Name
And you request JSON (through an Accept header) the response will be:
{
"d" : {
"Name": "Bread"
}
}
The "d" wrapper is there only to avoid XSS attacks so that must not be included in the requests, but the rest stays the same, so if you then send a PUT request like this:
PUT http://services.odata.org/(S(kupqbta5wqnfz2cln1qk052x))/OData/OData.svc/Products(0)/Name HTTP/1.1
Host: services.odata.org
Content-Type: application/json
Content-Length: 20
{
"Name": "Meat"
}
It will update the property Name to value Meat. You can also send a PUT to the value itself, in which case the URL would end with $value (denotes the raw value of the property) like this:
PUT http://services.odata.org/(S(kupqbta5wqnfz2cln1qk052x))/OData/OData.svc/Products(0)/Name/$value HTTP/1.1
Host: services.odata.org
Content-Type: text/plain
Content-Length: 4
Meat
Note that this only works on primitive properties though.
The sample service on the odata.org allows you to make modifications (guarded by the session key in the URL), so can play with it there.
Google for the HTTP 1.1 specification.

How do I extract "eTag" or "x-ms-request-id" from my Astoria DataContext response?

The Azure table whitepaper mentions that the x-ms-request-id is useful to send to Microsoft in the event there is an error working with the data. If I do have such an error, I'd like my try...catch block to take this and save it somewhere for future analysis.
In addition I need to extract the ETag value as well while in Table storage.
How do I extract this information and have it available when the Exception comes around?
HTTP/1.1 204 No Content
Content-Length: 0
ETag: W/"datetime'2008-10-01T15%3A27%3A34.4838174Z'"
x-ms-request-id: 7c1b5e22-831d-403c-b88a-caa4443e75cb
Depends on your client implementation, but they are all HTTP 1.1 headers.
For example, ( Assuming .NET WebRequest Class ) something like:
WebRequest request = WebRequest.Create("http://myazurestore.server.com");
....
WebResponse response = request.GetResponse();
string mSRequestId = response.Headers["x-ms-request-id"];
Would work
EDIT(for Storage Client Lib) ...
If you are using the Client library, you can get at ETag from the Properties collection on CloudBlob
So ..
Cloudblob blob = container.GetBlobReference("blobname.ext");
var eTag = blob.Properties.ETag
Properties is a blobProperties object. It should provide access to most of the needed data.
MSDN: http://msdn.microsoft.com/en-us/library/microsoft.windowsazure.storageclient.blobproperties_members.aspx
You may want to check out my open source Azure Table Storage Client project on CodePlex.
Lucifure Stash allows easy access to the ETag as well as the HttpWebRequest and HttpWebResponse objects.