Context
Often, in NetSuite, we find ourselves needing to invoke a RESTlet from another script. Typically, this requires using the N/https module, which prevents the direct use of the script’s internal URL. Instead, we’re faced with setting up an authorization Header in the RESTlet, a task both intricate and demanding in terms of maintenance. In order to do so, we have to create an Integration Record, use generated secret keys to be used as part of the creation of an oAuth1 header to then make the request to the external URL of the RESTlet. This leads to another problem where we also should keep these credentials securely for the only purpose of calling a RESTlet that resides in our own infrastructure and it is supposed to be called internally, most probably sharing the same credentials of the current user.
Alternatively, choosing to utilize a Suitelet without proper login, while seemingly an option, is strongly discouraged and should be entirely avoided as it contravenes established security protocols and best practices. This approach is prohibited due to the considerable security vulnerabilities it introduces, and adherence to this restriction is paramount for maintaining the integrity and safety of NetSuite.
Solution
To achieve the aforementioned goal, we have set up a RESTlet which will be invoked by a Suitelet. Below is a basic example of such a RESTlet. This sample RESTlet is designed to return the current user’s name, their role, and the role under which the RESTlet is operating.
/**
*@NApiVersion 2.1
*@NScriptType Restlet
*/
define(['N/runtime'], function(runtime){
return{
'get': function(params) {
var user = runtime.getCurrentUser();
return JSON.stringify({
name: user.name,
role: user.roleId,
currentRole: runtime.Permission.FULL,
});
}
}
});
Then we should define a Suitelet that will be the script that actually inovkes this RESTlet.
/**
* @NApiVersion 2.1
* @NScriptType Suitelet
*/
define(['N/https'], function(https) {
return {
onRequest: function(context) {
var response = https.requestRestlet({
deploymentId: 'customdeploy_sdn_testrestlet',
method: 'GET',
scriptId: 'customscript_sdn_testrestlet',
});
context.response.write(JSON.stringify({
response: JSON.parse(response.body),
}))
},
};
});
The crux of this solution lies in utilizing the function https.requestRestlet(). This function is pivotal as it sends an HTTPS request to a RESTlet and retrieves the response. Unlike standard HTTP requests, https.requestRestlet() uniquely automates the addition of authentication headers. As a result, the RESTlet operates with the same access privileges as the script that initiated the call, seamlessly integrating security and functionality.
Bonus
While it’s generally recommended to adhere to best practices by using SuiteScript 2.x (preferably version 2.1), there are certain scenarios where SuiteScript 1.0 remains necessary. This is particularly true in instances involving Plugins that have yet to support SuiteScript 2.x. In such cases, an alternative solution exists, which involves leveraging a specific function tailored for SuiteScript 1.0 environments. This function offers a compatible way to manage these exceptions while maintaining effective script execution.
nlapiRequestRestlet(String scriptId, String deploymentId, Map<String, String> urlParams, Object body, Map<String, String> headers, String method) throws Exception
Here is an example of a simple request using this function:
const response = nlapiRequestRestlet(scriptId, deploymentId, null, JSON.stringify(data), headers, 'POST')