The CreatorCon Call for Content is officially open! Get started here.

Scripted REST API or OOTB API

Joshua Cassity
Kilo Guru

We have a requirement to allow an external system to submit an item out on our service catalog.   Here's what we are doing using the 'Buy Item' resource using the 'SN_SC' api:

1. Peoplesoft initiates a REST call to begin an onboarding catalog item once approval is gathered for the hire. (this is working)

2. RITM is created and populated with that employee's information. (this is working)

3. Response is sent back to Peoplesoft with the RITM number to save on the approval record.

Item 3 poses an issue for us because the response only gives the REQ number and we really need the RITM number to be sent back in the response (which they'll store in their system) instead because if they need to update the RITM with new information (say Mary's last name changes during onboarding because she got married or her first day was going to be Monday but is now Friday, etc...).

Is the only way to handle such a thing is to create a scripted REST api (which we've never done before so it'll be a learning curve for me) or is there some other mechanism in the header or body to specify what needs to go back in the response?

Thanks for your assistance.

24 REPLIES 24

I did in the first paragraph.. it's the SN_SC api or Service Catalog.


Ah sorry, so you did, i was getting confused by the namespace.



I can't see anything in the docs that suggest you can customise what fields you get back so i think the only way will be to make a second API call.



Given that most items have workflow behind them that may fire asynchronously after being ordered and set values on the item, i think a second API call will be required to ensure you are getting the most upto date values anyway.


PeopleSoft is the 'record of truth' so we wouldn't be pushing any other data to them other than the RITM number. They hold all the employee information and would be updating that initial requested item only if something major changed such as a expected work date, retire date, etc....



We're simply the middle man for them to try to get a head start giving people access, setting up a workstation, wifi account, etc...



I guess if push comes to shove we'd just have to have them make two calls with the first call to create the RITM and then make a second scheduled call every night to try to find the RITM number associated with that request - which honestly seems like a lot of hassle because the people who run our PeopleSoft environment had a heck of a time figuring how to make the initial call to begin with.



Just trying to make this a simple a process as possible for all involved.


The one we are using I don't see documented anywhere: POST https://{instance_name}.service-now.com/api/sn_sc/servicecatalog/items/{sys_id}/order_now



In the explorer it's called 'Buy Item'.



find_real_file.png


Looking into the code, this is what you are dealing with: sys_ws_operation.do?sys_id=4f9131449f901200d54dd4b4232e708d



I followed the code through and its not going to return you the RITM.



So based on your requirement to keep things simple what i suggest you do is to create a new resource under the Service Catalog API. The new resource should be a duplicate of the out of the box "Order Now". but then modify the script so that it does an extra look up at the end to find the RITM from the request and append that to the returned object.



your script should look something like:



(function process(/*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {


        var request_body = request.body.nextEntry();


        var quantity = '' + request_body.sysparm_quantity;



        if (!/^\+?([0-9]*)$/.test(quantity))


                  throw new sn_ws_err.BadRequestError("Invalid Quantity value");


        else


                  request_body.sysparm_quantity = quantity;




        var itemId = '' + request.pathParams.sys_id;


        request_body.sysparm_id = itemId;


        var catItem = new sn_sc.CatItem(itemId);


        if (!catItem.canView())


                  throw new sn_ws_err.BadRequestError("Security constraints prevent ordering of Item");




        var catUtil = new RestCatalogUtil();


        if (!catUtil.checkMandatoryVariables(itemId, request_body.variables))


                  throw new sn_ws_err.BadRequestError('Mandatory Variables are required');




        var cart = new sn_sc.CartJS("cart_" +itemId);


        request_body.sysparm_cart_name = "cart_" +itemId;


        try {


                  var cartResult = cart.orderNow(request_body);



                  var ritmGR = new GlideRecord('sc_req_item_list');


                  ritmGR.addQuery('request', cartResult.request_id);


                  ritmGR.setLimit(1);


                  ritmGR.query();


                  if (ritmGR.next() {


                            cartResult.ritm_id = ritmGR.getValue('sys_id');


                            cartResult.ritm_number = ritmGR.getValue('number');


                  }



                  return cartResult;


        }catch(e) {


                  gs.debug(e);


                  throw new sn_ws_err.NotFoundError("Invalid Request");


        }


})(request, response);