{ Community }
  • Academy
  • Docs
  • Developers
  • Resources
    • Community Articles
    • Apigee on GitHub
    • Code Samples
    • Videos & eBooks
    • Accelerator Methodology
  • Support
  • Ask a Question
  • Spaces
    • Product Announcements
    • General
    • Edge/API Management
    • Developer Portal (Drupal-based)
    • Developer Portal (Integrated)
    • API Design
    • APIM on Istio
    • Extensions
    • Business of APIs
    • Academy/Certification
    • Adapter for Envoy
    • Analytics
    • Events
    • Hybrid
    • Integration (AWS, PCF, Etc.)
    • Microgateway
    • Monetization
    • Private Cloud Deployment
    • 日本語コミュニティ
    • Insights
    • IoT Apigee Link
    • BaaS/Usergrid
    • BaaS Transition/Migration
    • Apigee-127
    • New Customers
    • Topics
    • Questions
    • Articles
    • Ideas
    • Leaderboard
    • Badges
  • Log in
  • Sign up

Get answers, ideas, and support from the Apigee Community

  • Home /
  • General /
avatar image
1
Question by Dino · Feb 16, 2017 at 01:31 AM · 10.7k Views javascripthttpclientwaitforcomplete

Using httpClient from within JavaScript callout, is waitForComplete() necessary?

Suppose I would like to have a JS callout send a "fire and forget" request. Is it possible?

I know that I can use the httpClient to perform asynchronous requests. For example, in the request flow, I can have this JS:

var r = httpClient.get("https://google.com");
// set the pending request into a context variable
context.setVariable('pendingResponse', r); 

...and then follow it up with a companion JSC in the response flow that does something like this:

var r = context.getVariable('pendingResponse');
if (r) {
    // retrieve the pending request from the context variable
    r.waitForComplete();
    if (r.isSuccess()) {
      context.setVariable('asyncResponseContent', r.getResponse().content);
    }
}

What that combination of things does is: it sends the HTTP GET during the request flow, then does not block. Apigee may then invoke the target. Then, in the response flow, the JSC blocks for the response to the GET, and retrieves the contents.

My question is, suppose the request is a POST, and I don't care about the response at all?

Can I just omit the r.waitForComplete() part ? Will the http request complete as desired?

Comment
Add comment
10 |5000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by Apigeeks only
  • Viewable by the original poster
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Close

1 Answer

  • Sort: 
avatar image
2
Best Answer

Answer by Dino   · Feb 16, 2017 at 02:52 AM

Yes, it is possible to use the httpClient without calling waitForComplete() .

You might want to do this to avoid introducing latency in the proxy request or response flow. The HTTP request will actually complete, but the proxy flow will not wait for it.

For example, suppose you are sending a log message out to a log aggregation service, over HTTP. It might require 100ms in round-trip time to send that log message. Rather than forcing your API Proxy to wait for that log message to complete, before returning a response to the client, you can just omit the waitForComplete(), and respond "right now" to the client.

Example working JS code:

// log-To-Stackdriver.js
// ------------------------------------------------------------------
//
// Send a POST to stackdriver without waiting for a response.
//
// created: Wed Feb 15 16:28:55 2017
// last saved: <2017-February-15 18:43:10>


var variableNameRe = "[^ \t\n\"',/\\\\]+?"; // non-greedy capture
var varPrefixRe = '{';
var varSuffixRe = '}';
var variableRegex = new RegExp( varPrefixRe + '(' + variableNameRe + ')' + varSuffixRe, 'g');


function fillTemplate(template) {
  // substitute all names surrounded by {curly_braces} in the template
  // with the value of the corresponding context variables
  var match;
  while ((match = variableRegex.exec(template)) !== null) {
    var variableName = match[1];
    var value = context.getVariable(variableName);
    if (value && value !== '') {
      template = template.replace('{' + variableName + '}', value);
    }
    else {
      template = template.replace('{' + variableName + '}', 'n/a');
    }
  }
  return template + ''; // coerce to JS String
}


// fire and forget
var payload = fillTemplate(properties.payload);
var headers = {
      'Content-Type' : 'application/json',
      'Authorization' : fillTemplate(properties.authz_header)
    };
var url = fillTemplate(properties.endpoint);
var req = new Request(url, 'POST', headers, payload);
var exchange = httpClient.send(req);

Companion Policy configuration:

<Javascript name='JS-Log-To-Stackdriver' timeLimit='400'>
  <Properties>
    <Property name='authz_header'>Bearer {stackdriver.token}</Property>
    <Property name='payload'>{
  "logName": "projects/{stackdriver.projectid}/logs/{stackdriver.logid}",
  "resource" : {
    "type": "api",
    "labels": {}
  },
  "labels": {
      "flavor": "test"
  },
  "entries": [{
      "severity" : "INFO",
      "textPayload" : "{stackdriver.logpayload}"
     }
  ],
  "partialSuccess": true
}</Property>
    <Property name='endpoint'>https://logging.googleapis.com/v2/entries:write</Property>
  </Properties>
  <ResourceURL>jsc://log-To-Stackdriver.js</ResourceURL>
</Javascript>

Doing it this way means your API proxy logic will not be able to catch errors if the log aggregation service begins rejecting requests. Therefore you should use this "fire and forget" pattern if and only if you have some other way to ensure that your messages are flowing through to the external system. For example, some after-the-fact correlation of log messages or transaction IDs. Or even a gross count of transactions.

Comment
Add comment Show 2 · Link
10 |5000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by Apigeeks only
  • Viewable by the original poster
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Dino ♦♦   · Feb 16, 2017 at 10:01 PM 2
Link

Yes, I am aware that I answered my own question.

And now I'm commenting on my answer to my question.

avatar image psunda · Dec 11, 2017 at 01:21 PM 0
Link

@Dino How do we invoke 2 way SSL using the above approach? I know its possible in Node JS. But is it possible in Javascript?

Follow this Question

Answers Answers and Comments

41 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

What is the default timeout for httpClient calls made through Javascript? 1 Answer

Querying Amazon Web Services through Apigee 1 Answer

Get MessageId from Javascript 1 Answer

JavaScript callback support in httpClient is not working 1 Answer

How to find find where apigee store client coming request per second QPS policy in Cassandra table 0 Answers

  • Products
    • Edge - APIs
    • Insights - Big Data
    • Plans
  • Developers
    • Overview
    • Documentation
  • Resources
    • Overview
    • Blog
    • Apigee Institute
    • Academy
    • Documentation
  • Company
    • Overview
    • Press
    • Customers
    • Partners
    • Team
    • Events
    • Careers
    • Contact Us
  • Support
    • Support Overview
    • Documentation
    • Status
    • Edge Support Portal
    • Privacy Policy
    • Terms & Conditions
© 2021 Apigee Corp. All rights reserved. - Apigee Community Terms of Use - Powered by AnswerHub
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Create an article
  • Post an idea
  • Spaces
  • Product Announcements
  • General
  • Edge/API Management
  • Developer Portal (Drupal-based)
  • Developer Portal (Integrated)
  • API Design
  • APIM on Istio
  • Extensions
  • Business of APIs
  • Academy/Certification
  • Adapter for Envoy
  • Analytics
  • Events
  • Hybrid
  • Integration (AWS, PCF, Etc.)
  • Microgateway
  • Monetization
  • Private Cloud Deployment
  • 日本語コミュニティ
  • Insights
  • IoT Apigee Link
  • BaaS/Usergrid
  • BaaS Transition/Migration
  • Apigee-127
  • New Customers
  • Explore
  • Topics
  • Questions
  • Articles
  • Ideas
  • Badges