I'm trying to make a http get request in genexus, but in the object httpclient i can't find the property that have the answer and the method Execute() don't return the response of the request.
I need to copulate the json response in one SDT.
I try something like:
&httpClient = new()
&httpClient.BaseUrl = 'https://maps.googleapis.com/maps/api/geocode/json?latlng=' + &LocalLatitudeA + ',' + &LocalLongitudeA + '&key=xxxxxxxxxxxxx'
&httpClient.Execute('GET', &httpClient.BaseUrl)
You can do this to retrieve data from an HTTP endpoint and load a SDT with the result:
&HttpClient.Execute(!"GET", !"https://reqres.in/api/users?page=2")
&Users.FromJson(&HttpClient.ToString())
&HttpClient.ToString() returns the response as a string, and &Users.FromJson() loads the &Users SDT with the received data.
Related
I have a url:
https://cn.company.com/appv2/search
and want to have a different map local depending on the request coming with a different parameter in the body (i.e. it is NOT attached to the url like https://cn.company.com/appv2/search?cursor=abc. Instead it is in the body of the request { cursor: abc }.
Any idea on if this can be done in proxyman?
I basically want to be able to stub pagination through the proxy without waiting on a server implementation. So I'd have no cursor on the first request, server would return a cursor and then use that on the next request and get a different response from server on the request so that I can test out the full pagination flow.
Yes, it can be solved with the Scripting from Proxyman app.
Use Scripting to get the value of the request body
If it's matched, use Scripting to mimic the Map Local (Mock API also supports)
Here is the sample code and how to do it:
Firstly, call your request and make sure you can see the HTTPS Response
Right-Click on the request -> Tools -> Scripting
Select the Mock API checkbox if you'd like a Mock API
Use this code
/// This func is called if the Response Checkbox is Enabled. You can modify the Response Data here before it goes to the client
/// e.g. Add/Update/Remove: headers, statusCode, comment, color and body (json, plain-text, base64 encoded string)
///
async function onResponse(context, url, request, response) {
// get the value from the body request
var cursorValue = request.body["cursor"];
// Use if to provide a map local file
if (cursorValue === "abc") {
// Set Content Type as a JSON
response.headers["Content-Type"] = "application/json";
// Set a Map Local File
response.bodyFilePath = "~/Desktop/my_response_A.json";
} else if (cursorValue === "def") {
// Set Content Type as a JSON
response.headers["Content-Type"] = "application/json";
// Set a Map Local File
response.bodyFilePath = "~/Desktop/my_response_B.json";
}
// Done
return response;
}
Reference
Map Local with Scripting: https://docs.proxyman.io/scripting/snippet-code#map-a-local-file-to-responses-body-like-map-local-tool-proxyman-2.25.0+
On the site "example.net" I have standart api method to take access token (which i can call /Token) and if I make POST request using Fiddler to example.net/Token with parameters in request body
And all is OK. Status code 200 and in the response access token and other info.
But if I do this request from other site using RestSharp - 500 Internal Server Error. I tried to AddParameter, AddBody, AddObject. Make parameters as a JSON string, to change DataFormat, to AddHeader of Content-Type. This is my last version of request.
request = new RestRequest(URL, Method.POST);
//request.AddHeader("Content-Type", ContentType);
string UrlEncoded = "";
//I parse Parameters to format like I use in request body in Fiddler.
if (Parameters.Count != 0)
foreach (var param in Parameters)
UrlEncoded = param.ParamToUrlEncoded(UrlEncoded);
request.AddBody(UrlEncoded);
IRestResponse response = client.Execute(request);
var content = response.Content;
Do i need to set any more attributes on the request or something?
Thank you.
I want to do an integration test for the below action.
How can I pass my requestDto object in the integration test?
Neither the GetAsync nor SendAsync method has an overload parameter to pass a custom object to the server.
[Route("{startDate:datetime}")]
[HttpGet]
public HttpResponseMessage Get(DateTime startDate, [FromBody]LessonplannerGetRequest request)
{
request.StartDate = startDate;
var lessonplannerResponse = _service.GetPeriodsByWeekStartDate(request);
return Request.CreateResponse<LessonplannerResponse>(HttpStatusCode.OK, lessonplannerResponse);
}
[Test]
public void Get_Lessons_By_Date()
{
// Arrange
var request = new HttpRequestMessage(HttpMethod.Get, _server.BaseAddress + "/api/lessonplanner/2014-01-14");
var myRequestDto = new LessonplannerGetRequest();
// Act => QUESTION: HOW do I pass the myRequestDto ???
var response = _client.SendAsync(request, new CancellationToken()).Result;
// Assert
Assert.That(response.StatusCode == HttpStatusCode.OK);
}
UPDATE
As Darrel Miller said:"Technically HTTP says you can send a body, it just says the body doesn't mean anything and cannot be used. HttpClient won't let you send one."
I post here my integration test with HttpClient doing a Get request with complex type + FromBody:
// Arrange
var request = new HttpRequestMessage(HttpMethod.Get, _server.BaseAddress + "/api/lessonplanner/2014-01-14");
var myRequestDto = new LessonplannerGetRequest{ FirstDayOfWeek = DayOfWeek.Sunday, SchoolyearId = 1, StartDate = DateTime.Today};
request.Content = new ObjectContent<LessonplannerGetRequest>(myRequestDto, new JsonMediaTypeFormatter());
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// Act
var response = _client.SendAsync(request, new CancellationToken()).Result;
// Assert
Assert.That(response.StatusCode == HttpStatusCode.OK);
Of course is this is not the Http way some might consider doing it differentlly sending complex type via FromUri/query string.
HTML specifications says you cannot send a GET with a body.
HTTP specs allows it.
WebAPI allows it, because it is a service/REST and implements HTTP but not HTML, but many clients and browser won't allow it because they implement both specs and try to be strict.
As for the specifications (RFC1866, page 46; HTML 4.x section 17.13.3) itself, it states:
If the method is "get" and the action is an HTTP URI, the user agent takes the value of action, appends a `?' to it, then appends the form data set, encoded using the "application/x-www-form-urlencoded" content type.
(e.g. if you do a <form> with GET, it will parse all the form params and set them in the query string ?a=b).
In term of pure HTTP and in the context of REST services, nothing prevents that behavior, but not all clients will be able to handle it. It's mostly a best-practice advise when it comes to REST/WebAPI to not handle body data from HttpGet, only URI data (the opposite, POST /action?filter=all is usually tolerated for metadata/action qualifiers, but that's another discussion).
So yeah, it's at your own risk, even if used only internally. As not all clients handle it (e.g. HttpRequestMessage), so you might run into trouble like you have.
You should NOT pass a GET body with HTTPClient.
I want to fetch a list of all Salesforce objects.
I found this link
http://wiki.developerforce.com/index.php/Enterprise_Describe_Global
but there are some issues:
1) Missing session(Invalid session id)
To prevent this i appended the session key in the url also for the post request but it shows no request.
Error : Internal Server Error (500)
2) I found somewhere and added clientId along with the session header but again no response.
Error : Internal Server Error (500)
code sample of web request:
HttpRequest req = new HttpRequest();
Http http = new Http();
req.setMethod('POST');
req.setHeader('content-type','text/xml;charset=utf-8');
req.setHeader('Content-Length','1024');
req.setHeader('Host','na1.salesforce.com ');
req.setHeader('Connection','keep-alive');
req.setHeader('soapAction', 'getObjects');
String url = 'https://na1.salesforce.com/services/Soap/c/10.0/session_key';
String str = '<?xml version="1.0" encoding="utf-8"?> '+
'<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:urn=\"urn:enterprise.soap.sforce.com\">'+
'<soapenv:Header>'+
'<urn:SessionHeader>'+
'<urn:sessionId>'+'session_ID'+'</urn:sessionId>'+
'</urn:SessionHeader>'+
'<urn:CallOptions><urn:client>CLIENT_ID</urn:client></urn:CallOptions>'+
'</soapenv:Header>'+
'<soapenv:Body>'+
'<describeGlobal></describeGlobal>'+
'</soapenv:Body>'+
'</soapenv:Envelope>';
req.setEndpoint(url);
req.setBody(str);
HTTPResponse resp = http.send(req);
system.debug('response:::'+xml_resp);
Session_ID : I got this value from UserInfo.getSessionID();
client_ID : I tried following values : UserInfo.getUserID();/Secret token
but i couldnt make it a perfect call to get reaponse.
Hope somebody can help...
Why are you using an outbound web service call in Apex? Apex has native access to global describe information using Schema.getGlobalDescribe() - which is a much better way to access describe results.
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_methods_system_schema.htm has the full documentation for calling this from Apex.
I am facing a problem, while encoding the response that I send back for an AJAX request, using GZIP. Can anyone give me some pointers on this please?
There is an AJAX request from the JSP,
An action class (Struts) at the server side handles the request,
The response is prepared as a JSON object,
The JSON string is written to the Response object and sent back,
the JSON string is read from the responseText property of the xmlHttp object back at the jsp
This works fine. However, instead of sending the raw JSON data, if I send back encoded JSON data, then there are issues.
Server Side Code to create GZip'ed JSON :
// jsonStr = JSONObj.toString();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(bos);
gzip.write(jsonStr.getBytes());
gzip.close();
String newStr = new String(bos.toByteArray());
// set the response header and send Encoded JSON response
response.setHeader("Content-Type", "application/json");
response.setHeader("Content-Encoding", "gzip");
response.setHeader("Vary", "Accept-Encoding");
pw = response.getWriter();
pw.write(newStr);
pw.close();
At the JSP :
// marker
alert('Length of the received Response Text : ' + xmlHttp.responseText.length);
// evaluate the JSON
jsonStr = eval('(' + xmlHttp.responseText + ')');
The alert box, on receiving the response, reports length as 0!