• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Need To Replicate a cURL call With CFHTTP

New Here ,
Jan 17, 2023 Jan 17, 2023

Copy link to clipboard

Copied

Hello:

I need to replicate the following cURL call, which uses a multipart/form-data header and form fields:

 

curl -L -R POST "https://api.XXXXXXXX.com/api/v1/academic_success/sync/enrollment" \
-H "Authorization: Bearer <access_token>" \ # Generated OAuth2 token request
-H "Content-Type: multipart/form-data" \
-F "input_type=CSV" \
-F "input_data=@enrollment_upload.csv" \ # Path to CSV file. Include '@' before path.
-F "dry_run=false" \ # Set to true when testing
-F 'drop_not_passed_enrollments=true' \ # only enabled when dry_run = false

 

CFHTTP does not allow specifying form fields for multi-part data. I assume I'd have to code a header that included the form fields as part of the body along with the data, but am unclear on how to do this. We are currently production with CF 2018.

Thanks.

Gerry, Pace University

 

Views

424

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 18, 2023 Jan 18, 2023

Copy link to clipboard

Copied

Could you please share the cfhttp code that you used.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jan 18, 2023 Jan 18, 2023

Copy link to clipboard

Copied

BKBK:

Thank you for getting back to me. The code is below, I assume it needs to have request headers for the form variables added, along with multi part header commented out in the CFHTTPPARAM. Just not sure of the exact specification for the headers and their order, I assume the form variables would come before the data (CSV) being sent.

Gerry, Pace University

<CFSCRIPT>

REQUEST.ApiEnrollment = "http://httpbin.org/post"

 

// The contents for the BODY, but need to include headers for the form variable
REQUEST.LoadBody = "" ;
REQUEST.LoadBody = REQUEST.LoadBody & "input_type=CSV&" ;
REQUEST.LoadBody = REQUEST.LoadBody & "dry_run=true&" ;
REQUEST.LoadBody = REQUEST.LoadBody & "input_data=" & REQUEST.DataBlob ;
REQUEST.LoadBody = UrlEncodedFormat( REQUEST.LoadBody ) ;

CFHttp( Url="#REQUEST.ApiEnrollment#" , Method="POST" , ThrowOnError="YES" , MultiPart="YES" , MultiPartType="RELATED" , TimeOut="450" )
{
CFHttpParam( Type="Header" , Name="Authorization" , Value="#REQUEST.Token#" ) ;
CFHttpParam( Type="Header" , Name="X-TW-PersonId" , Value="#REQUEST.XTWPersonId#" ) ;
// CFHttpParam( Type="Header" , Name="Content-Type:" , Value="multipart/form-data" ) ;
// CFHttpParam( Type="FormField" , Name="input_type" , Value="CSV" ) ;
// CFHttpParam( Type="FormField" , Name="input_data" , Value="#REQUEST.CsvName#" ) ;
// CFHttpParam( Type="FormField" , Name="dry_run" , Value="true" ) ;
CFHttpParam( Type="Body" , Value="#REQUEST.LoadBody#" ) ;
}

WriteOutput( '<br/>***** PROGRAM: Send Student Data</br></br>' ) ;
WriteOutput( 'Return Code Is ' & CFHTTP.StatusCode ) ;
WriteOutput('<br/><br/>') ;

Returned = deserializeJSON( CFHttp.FileContent ) ;
WriteDump( Var="#Returned#" , Label="Returned Variables" ) ;

</CFSCRIPT>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 18, 2023 Jan 18, 2023

Copy link to clipboard

Copied

The instructions at http://httpbin.org suggest you might be able to send JSON data. If so, then you could do it simply, without any need for multipart/form-data.

 

Try something like:

REQUEST.DataBlob=fileread("full_path_to_CSV_file");
REQUEST.ApiEnrollment="API_URL";
	
REQUEST.LoadBody=structNew();
REQUEST.LoadBody.input_type="CSV";
REQUEST.LoadBody.dry_run="true";
REQUEST.LoadBody.input_data=REQUEST.DataBlob;


CFHttp( Url="#REQUEST.ApiEnrollment#" , Method="POST" , ThrowOnError="YES", TimeOut="450" )
{
	CFHttpParam( Type="Header" , Name="Authorization" , Value="#REQUEST.Token#" );
	CFHttpParam( Type="Header" , Name="X-TW-PersonId" , Value="#REQUEST.XTWPersonId#" );
	Cfhttpparam( Type="Header" , Name="Content-Type" , value="application/json");
	CFHttpParam( Type="Body" , Value="#serializeJson(REQUEST.LoadBody)#" ) ;
	 
}

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jan 19, 2023 Jan 19, 2023

Copy link to clipboard

Copied

BKBK:

First, apologies on the delayed response, I'm severely slammed on time with another project. I hope that httpbin.org are correct ! I will given it a try as soon as I can, probably this evening.

Thank you again for the assistance -- it is much appreciated.  Have a great day !

Gerry, Pace University

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 19, 2023 Jan 19, 2023

Copy link to clipboard

Copied

No worries, Gerry.

Wishing you lots of fun with the projects! 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jan 25, 2023 Jan 25, 2023

Copy link to clipboard

Copied

BKBK:  let me first apologize for not responding sooner. I just got a chance a little while ago to run your code, it failed though it mentioned the request was well formed (see message below). The field that the says was missing, you did have in code. It appears that the site couldn't parse the payload correctly.  I get the feeling that I will need do boundary headers for the form fields manually and add them to body to get it to be consumed properly. Again, apologies for the very late response, I am very appreciative of your assisting us  in this matter.  Gerry, Pace University

 

Return Code Is 422 UNPROCESSABLE ENTITY

Returned Variables - struct

messageThe request was well-formed but was unable to be followed due to semantic errors.
messagesReturned Variables - struct
input_typeReturned Variables - array
1Missing data for required field.
status422

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 26, 2023 Jan 26, 2023

Copy link to clipboard

Copied

The error message suggests that the API understands the request, but perhaps requires a slightly different representation. So what happens when you send a JSON rather than a JSON string. That is, test with the following line

CFHttpParam( Type="Body" , Value=#serializeJson(REQUEST.LoadBody)# ) ;

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jan 26, 2023 Jan 26, 2023

Copy link to clipboard

Copied

BKBK: I did, I used the exact code you sent, with the one exception of course of it going to the actual vendor site. Below is the code that was run.  Gerry

 

<CFSCRIPT>

// Code From BKBK

//REQUEST.ApiEnrollment = "http://httpbin.org/post"

//REQUEST.DataBlob=fileread("full_path_to_CSV_file");
//REQUEST.ApiEnrollment="API_URL";

REQUEST.LoadBody=structNew();
REQUEST.LoadBody.input_type="CSV";
REQUEST.LoadBody.dry_run="true";
REQUEST.LoadBody.input_data=REQUEST.DataBlob;

CFHttp( Url="#REQUEST.ApiEnrollment#" , Method="POST" , ThrowOnError="YES", TimeOut="450" )
{
CFHttpParam( Type="Header" , Name="Authorization" , Value="#REQUEST.Token#" );
CFHttpParam( Type="Header" , Name="X-TW-PersonId" , Value="#REQUEST.XTWPersonId#" );
Cfhttpparam( Type="Header" , Name="Content-Type" , value="application/json");
CFHttpParam( Type="Body" , Value="#serializeJson(REQUEST.LoadBody)#" ) ;
}

WriteOutput( '<br/>***** PROGRAM: Send Student Data</br></br>' ) ;
WriteOutput( 'Return Code Is ' & CFHTTP.StatusCode ) ;
WriteOutput('<br/><br/>') ;

Returned = deserializeJSON( CFHttp.FileContent ) ;
WriteDump( Var="#Returned#" , Label="Returned Variables" ) ;

</CFSCRIPT>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 19, 2023 Feb 19, 2023

Copy link to clipboard

Copied

And did that work?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Feb 22, 2023 Feb 22, 2023

Copy link to clipboard

Copied

BKBK: Will update tomorrow with code, and form vars setup boundary separaters. Thanks for checking back. Gerry

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Feb 24, 2023 Feb 24, 2023

Copy link to clipboard

Copied

LATEST

BKBK:

Attached is the latest code version with everything stuffed into the body. Returns a 200 ok from the http://httpbin.org/post, it did not find anything with the boundary separator coding, but that is not unusal with that site. I won't be able to run it against the vendor test till next Monday. The code file is attached. Have a great weekend. Gerry

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Documentation