Synthetics API Tests

Hi,

I am new to New Relic and need to write API Tests. I have lets say 15 methods for which I need to write tests. There exists a auth service which generates a bearer token that needs to be passed upon each subsequent request’s header. Also I need to do correlation(extracting a value from 1 request and passing to another request as a parameter) via callbacks using javascript… Can anyone help me achieving this???

Early response will be really helpful.

Hi @jain.raksh25, you can use my API synthetics sample as a basis

1 Like

+1 :blush: @jain.raksh25
@stefan_garnham 's sample/workaround is pretty darn great!

I have similar question but not sure how stefan’s script can help.

I have an API that does the authentication (will call it authentication API) and will store necessary data in cookie. I have other APIs that require the call to be in an authenticated state, basically the cookie from the authentication API call will be passed to these other APIs.

So lets say I want to monitor the authentication API and one of those APIs that require authenticated state, meaning I will have two separate monitors. I cant use the cookie from one monitor for another monitor, correct? If not, does it mean I must call the authentication API in each monitor that monitors an API that requires an authenticated state?

Thanks for any help.

Hi @HotChocolate, that is the first time I have heard of an authentication API setting a cookie. Usually an authentication API will return an authentication token which is then used to call the other API. I have not bothered to write a separate synthetic on the authorisation API as it is used on all of our other API synthetics.

If you have to have the cookie then you may need to write a scripted browser synthetic which calls your authentication API as the browser script would cover setting the cookie.

1 Like

@HotChocolate, @stefan_garnham - You can use Synthetics API tests to manage cookies for your scripted API tests. The Synthetics API test $http is simply a wrapper around node’s request module and you can see several examples of how to interact with cookies for an API test at https://github.com/request/request. If you need to manually manage your cookie jar, you can also import the tough-cookie node module as well.

@HotChocolate - As far as your question about the authentication API monitoring VS your other API monitoring, @stefan_garnham is correct, you cannot pass any data between different monitors so each monitor must run 100% standalone so if your service requires authentication, you must log in at the start of each script.

1 Like

Thank you stefan and sdelight.

Just clarifying I am not really passing the cookie, it is being created upon calling authentication API and as long as it exists the other APIs take the cookie and validates it.

Thanks for the toughcookie suggestion sdelight. I am not entirely sure but sounds like it might be something I can use for my purpose, basically getting all cookies that exist and do something with it. I did try the sample code but couldnt get it to work, there must be something I am doing wrong. Sample script below, cookies is always empty. Any idea?

var assert = require(‘assert’);
var tough = require(‘tough-cookie’);

var signInOptions = {
url: “https://www.somewebsite.com/authenticationAPI
};

// Callback
function signInCallback(err, response, body) {
console.log("SignIn status code: " + response.statusCode);
console.log('SignIn Response: ', body);

if(response.statusCode == 200)
{
var cookiejar = new tough.CookieJar();
cookiejar.getCookies(‘http://www.somewebsite.com’,function(err,cookies) {
console.log('cookies: ’ + cookies);
});
}
}

Have you checked whether there is an error in the getCookies call?

Good call! Let me do that. Thanks stefan.

1 Like

Console.log err and it returns nothing.

If the authorisation request provides a cookie in the response, then would you need to set that in your CookieJar?

I haven’t read the documentation around how it works so may be an idea to dig around there for more information on its usage.

@HotChocolate - Per the examples in the node request documentation If this authorization cookie is just needed to persist between requests you simply need to set jar: true. By default, cookies are disabled and so you simply need to enable them and then pass the default cookie jar along. It isn’t necessary to use the tough-cookie module unless you need to manually adjust your cookies.

2 Likes

Thanks for the tip sdelight, let me try it.

1 Like

Keep us posted, @HotChocolate! Would love to know if this sorted things for you!

Hi Everyone,

Finally I am back to try out the tip from sdelight. Still havent gotten it to work, will post back soon.

1 Like

I tried to google but didnt find much on how to persist cookies. I am unsure how to get it to work. This is what i have and i am getting a 200 so i expect to see the variable cookie storing the cookie collection in the current session but it is not. Or am I going a totally wrong direction:

var Options = {
//Define endpoint URL.
url: “https://www.website.com/api”,
//Define body of POST request.
body: ‘some body text’,
jar: true
};

// Callback
function Callback(err, response, body) {
console.log("status code: " + response.statusCode);
console.log('Response: ', body);

if(response.statusCode == 200)
{
var cookie = request.cookie();
console.log("cookie: " + cookie);
}
}

$http.post(Options, Callback);

Thanks for any pointer.

Hi @HotChocolate Thank you for the follow-up and providing the sample code! You may want to try setting a custom jar, via $http.jar() for the $http request. Here’s a modified version of your most recent code snippet:

var myJar = $http.jar();

var Options = {
	//Define endpoint URL.
	url: "https://www.website.com/api",
	//Define body of POST request.
	body: 'some body text',
	jar: myJar
};

// Callback
function Callback(err, response, body) {
console.log("status code: " + response.statusCode); 
console.log('Response: ', body);

if(response.statusCode == 200)
{
	var cookie = myJar.getCookies(Options.url);
	console.log("cookie: " + cookie);
}
}

$http.post(Options, Callback);

Additional examples are available at the very bottom of the following the page: https://github.com/request/request#examples

Let us know if this works out or if you have questions. Also, providing us a direct link to the Synthetics monitor you’re working on will help us out with troubleshooting.

Thanks!

1 Like

Thank you so much btribbia. That worked I can see the cookie values now.

Is there sample code to persist the cookie for the next call? I have updated my code to be the same as yours and have the code below for the subsequent call, it is not coming back with a 200. I must have missed something.

var Options2 = {
url: “https://www.website.com/api2”,
body: ‘some body text’,
headers: {
‘User-Agent’:‘curl/7.43.0’,
‘Content-Type’: ‘application/json’
},
jar: myJar
};

function Callback2(err, response, body) {
console.log("callback2 status code: " + response.statusCode);
}

$http.post(Options2, Callback2);

Hey, @HotChocolate - I am glad to hear my previous code sample helped out! The cookie jar variable should be persisting between calls so, what I’d like to confirm, is that the two calls are happening in the correct order. Assuming that the entire script so far consists of my previous code sample then the code sample you provided right after, there is nothing to ensure that the second call is happening after the first. You could try performing the second $http.post in the Callback of the first, after you’ve confirmed the first call returned a 200 response:

   //Within Callback of authentication API call
   if(response.statusCode == 200) {
   	var cookie = myJar.getCookies(Options.url);
   	console.log("cookie: " + cookie); 

   	$http.post(Options2, Callback2);

   }

Let me know if this works.

Thanks!

1 Like

Hi again @btribbia, and thanks for responding.

Yes that is exactly how I have it. Below is the code. It is failing and that is because it didnt get the cookie. The API works if i tested it on its own. I must not be passing the cookie right?!

var assert = require(‘assert’);
var request = require(‘request’);
var apiResponse = ‘’;
var myJar = $http.jar();

var FirstAPIOptions = {
url: “https://www.website.com/api/FirstApi”,
body: ‘some body’,
headers: {
‘User-Agent’:‘curl/7.43.0’,
‘Content-Type’: ‘application/json’
},
jar: myJar
};

// Callback
function FirstAPICallback(err, response, body) {
console.log("FirstAPI status code: " + response.statusCode);
console.log('FirstAPI Response: ', body);

if(response.statusCode == 200)
{
var cookie = myJar.getCookies(FirstAPIOptions.url);
console.log("cookie: " + cookie);
apiResponse = JSON.parse(body);
if(apiResponse.responseActionUrls.length == 1)
{
$http.post(SecondAPIOptions, SecondAPICallback);
//console.log(‘blah’);
}
}
else
{
assert.equal(response.statusCode, 200, ‘FirstAPI did not return a 200 response’);
}
}

var SecondAPIOptions = {
url: “https://www.website.com/api/SecondAPI”,
body: ‘some body’,
headers: {
‘User-Agent’:‘curl/7.43.0’,
‘Content-Type’: ‘application/json’
},
jar: myJar
};

// Callback
function SecondAPICallback(err, response, body) {
console.log("SecondAPI status code: " + response.statusCode);
console.log('SecondAPI response: ', body);

if(response.statusCode == 200)
{
apiResponse = JSON.parse(body);
}
else
{
assert.equal(response.statusCode, 200, ‘SecondAPI did not return a 200 response’);
}
}

$http.post(FirstAPIOptions, FirstAPICallback);