Apigee Api proxy - how to make asynchronous call - api

I have api that I would like to return to user as soon as the message is received by apigee. Do not wait for response from my service. Do you know how to do that using apigee api proxy?

The node.js method mentioned above is probably the most straight forward solution. Information on using node.js with Apigee can be found at http://apigee.com/docs/api-services/content/developing-nodejs-applications-apigee-edge

I believe you tried the initial right approach Kaszaq using httpClient get method. As it's been documented in Apigee Docs.
http://apigee.com/docs/api-services/content/javascript-object-model
https://github.com/apigee/api-platform-samples/blob/master/sample-proxies/async-callout/apiproxy/resources/jsc/callout.js
And yes, if you want a more robust solution try Node.js.
//
// Make 5 HTTP callouts to Yahoo weather to get the weather for 5 cities
// The calls are all asynchronous and execute in parallel
// httpClient returns an exchange object that will contain the HTTP response. . . when it arrives
//
var paloAlto = httpClient.get('http://weather.yahooapis.com/forecastrss?w=2467861');
context.session['paloAlto'] = paloAlto;
var anchorage = httpClient.get('http://weather.yahooapis.com/forecastrss?w=2354490');
context.session['anchorage'] = anchorage;
var honolulu = httpClient.get('http://weather.yahooapis.com/forecastrss?w=2423945');
context.session['honolulu'] = honolulu;
var newyork = httpClient.get('http://weather.yahooapis.com/forecastrss?w=2459115');
context.session['newyork'] = newyork;
var dublin = httpClient.get('http://weather.yahooapis.com/forecastrss?w=560743');
context.session['dublin'] = dublin;

As you have the liberty of customising API's using Node.js. You can use that to implement async behaviour in you api proxy.
For more info on customising api's using Node.js visit the following link-
http://apigee.com/docs/api-services/content/developing-nodejs-applications-apigee-edge

Related

Create a space with Google Chat REST API

We have a program that uses a service account to manage various thing inside Google Chat.
Now, we have the need to create a new space using the Google Chat REST API (spaces.create).
We already joined the developer preview program, as this endpoint is not yet generally available.
From what we understand, this endpoint is not possible to invoke via service account and so we wanted to ask you… can we invoke this endpoint automatically using “domain delegation”? If yes, how?
We always want to use the service account as it is not possible to show a login prompt to the user.
We enabled the domain delegation but that endpoint returns always status 403. (We are using Google.Apis library for .NET Core
using Google.Apis.Auth.OAuth2;
var credential = GoogleCredential.FromFile("key.json")
.CreateScoped("https://www.googleapis.com/auth/chat.spaces.create")
.CreateWithUser("service-account-email#project.iam.gserviceaccount.com");
var token = await credential.UnderlyingCredential.GetAccessTokenForRequestAsync();
HttpRequestMessage request = new(HttpMethod.Post, "https://chat.googleapis.com/v1/spaces");
request.Headers.Authorization = new("Bearer", token);
var payload = #"
{
""name"": ""testspace-1"",
""spaceType"": ""SPACE"",
""singleUserBotDm"": true,
""displayName"": ""Test Space""
}
";
request.Content = new StringContent(payload, System.Text.Encoding.UTF8, "application/json");
HttpClient client = new();
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
If you check the documentation Auth
You will notice it stats that service account authorization is supported. If you are part of thedeveloper preview program
The reason I asked about your code is that the last time i tried this which notably was a while ago. The google .net client library was not generated the methods that were under preview.
So while it may work yes. The issue your may have is that the client library when loaded will not have the method you need meaning you will have to code the call to the endpoint yourself.
If this is in fact the case let me know if you have any issues peceing it together I may be able to help.
update your code
There is an error in your code
.CreateWithUser("service-account-email#project.iam.gserviceaccount.com");
The email in CreateWithUser should be the user on your domain who you wish to delicate the service account as. Not the service account email address.

Service Now Api integration using client side script

I tried to integrate external soap based api using servicenow client side scipt options. My intention is to initiate an external api call when an incident is created.
But i am getting uncaught reference error sn_ws is not defined exception.
function onSubmit() {
try {
var s = new sn_ws.SOAPMessageV2('global.IQTrack', 'VerifyApiKey');
s.setStringParameterNoEscape('VerifyApiKey.apiKey', 'dfghdhgdjh');
var response = s.execute();
var responseBody = response.getBody();
var status = response.getStatusCode();
}
catch(ex) {
alert(ex);
}
}
Is this the way to initiate api call? If it is so why it is getting sn_ws is not defined.
That's because sn_ws is a server-side API.
You need to either use GlideAjax, or a client-side webservices API such as XMLHttpRequest.
You can find an excellent article on GlideAjax, here: http://snprotips.com/blog/2016/2/6/gliderecord-client-side-vs-server-side
If your aim is to initiate the message once a ticket is created, then you should definitely be doing this server-side, not in a client script.
I hope,sn_ws is a server-side API.
I think GlideAjax method will help you to get rid of this issues.
please go through below links,I think it will help you to sort out this issues.
http://wiki.servicenow.com/index.php?title=GlideAjax#gsc.tab=0
And alternative is use client-side webservices API like XMLHttpRequest

Send data to a REST API every time a new account is added to Salesforce

Sorry for the total newbie question here regarding triggers, but here is my scenerio:
What are some of the options available to send data to a 3rd party REST API every time a new account is added to Salesforce?
I have been initially looking at code examples for triggers on account after insert. In addition to this, is there a way using the SFDC streaming API? Any ideas on What API usage is best practice + code examples would be much appreciated.
Thanks in advance!
To be able to make callout from a trigger you need to make the callout asynchronous (using #future annotation) .
For example :
trigger AfterInsertAccount on Account (after insert){
futCls.asynchCallout(); //call a method with #future annotation
}
Class Code :
global futCls {
#future
Public static void asynchCallout(callout=true){
HttpRequest req = new HttpRequest();
req.setEndpoint('your 3rd party service URL goes here');
req.setMethod('GET');
Http http = new Http();
HTTPResponse res = http.send(req);
}
}
For more information refer to SFDC documentation.

Rest and ZF session management

I'm trying to create a web service which utilizes Zend framework. The API is REST based and uses Zend_Rest_Controller as base class. I wish to have user management and session, and for that I'm using the following code:
Login (POST)
// user id and password fetched first
$users = new Application_Model_DbTable_UserInfo();
$auth = Zend_Auth::getInstance();
$authAdapter = new Zend_Auth_Adapter_DbTable($users->getAdapter(),'users');
$authAdapter->setIdentityColumn('userid')
->setCredentialColumn('password');
$authAdapter->setIdentity($userid)
->setCredential($pwd);
$result = $auth->authenticate($authAdapter);
if($result->isValid()){
Zend_Session::rememberMe(604800);
$storage = new Zend_Auth_Storage_Session();
$usa = $authAdapter->getResultRowObject();
$auth->getStorage()->write($usa);
$authSession = new Zend_Session_Namespace('Zend_Auth');
$authSession->setExpirationSeconds(60*60);
}
and when accessing the service with e.g. some GET method I wish to check that there is a valid session with the following code:
$auth = Zend_Auth::getInstance();
if(!$auth->hasIdentity())
{
// error handling etc.
}
I never get an identity, hence the service doesn't work.
I have followed the guidance for ZF authentication quite strictly, but does the REST stuff need additional items to be taken into account?
I know I'm not answering your question, but if you are REALLY planning to implement a true REST interface (which implies it's going to enable you to scale well), you'd probably better forget about sessions and using Zend_Auth in the way you've depicted above.
Take a look here, where something about REST interfaces and authentication has been discussed already:
Can you help me understand this? "Common REST Mistakes: Sessions are irrelevant"
In short, quoting from the Q/A thread above, "To be RESTful, each HTTP request should carry enough information by itself for its recipient to process it to be in complete harmony with the stateless nature of HTTP". I really feel like seconding that.

How to send a request to an external API

I am new to Symfony2 and I'm trying to send a
new Request()
to and external API. This is what I have but I don't know if it is correct use of the built in request/response library.
$request = new Request('https://myservice.com/apimethod?foo=bar', 'GET');
Can anyone tell me if this will return a response provided the API I'm trying to call exists?! If not, what am I doing wrong?
In Symfony2, the Request class represents an HTTP request made to your site. Basically, if you go to www.yoursite.com/someaction Symfony instantiates aSymfony\Component\HttpFoundation\Request object. This object contains methods that you can use to examine the HTTP request (such as seeing if it contains GET or POST variables.)
This is a good explanation of Symfony and HTTP fundamentals. I also recommend looking at the source code for Request to see exactly what it can do.
In order to achieve what you're trying to do in your example, you'd need to use cURL. I personally use a wrapper class on top of cURL that you can find here.
Hope this helps.
https://github.com/CircleOfNice/CiRestClientBundle
It's the easiest way to send a request to an external API. It provides all http methods as functions and is easy to use.
$restClient = $this->container->get('ci.restclient');
$restClient->get('http://www.someUrl.com');
$restClient->post('http://www.someUrl.com', 'somePayload');
$restClient->put('http://www.someUrl.com', 'somePayload');
$restClient->delete('http://www.someUrl.com');
$restClient->patch('http://www.someUrl.com', 'somePayload');
$restClient->head('http://www.someUrl.com');
$restClient->options('http://www.someUrl.com', 'somePayload');
$restClient->trace('http://www.someUrl.com');
$restClient->connect('http://www.someUrl.com');
If you want to use rest clients just to CRUD entities then I think you should have a look at
https://github.com/CircleOfNice/DoctrineRestDriver
which helps you to get rid of manually sending requests and mapping responses because Doctrine is doing the job for you.
// Sends a GET request to http://$driverUrl/#TableAnnotation/1 and returns a valid MyEntity Entity
$entity = $em->find("Some\Namespace\MyEntity", 1);
Someone else answered a question like this: https://stackoverflow.com/a/10715549/2306587
You don't have to rely on cURL to make an external request. There is a Symfony-Bundle who can handle that: http://knpbundles.com/sonata-project/SonataGoutteBundle
Use Guzzle from here.
Exemple:
$client = new \GuzzleHttp\Client();
$res = $client->request('GET', 'https://api.github.com/repos/guzzle/guzzle');
echo $res->getStatusCode();