Direct Web Services

From ServiceNow Wiki
Home > Integrate > Web Services > SOAP Web Services > Direct Web Services
Jump to: navigation, search
Note
Note: This article applies to Fuji. For more current information, see Direct Web Services at http://docs.servicenow.com

The ServiceNow Wiki is no longer being updated. Please refer to http://docs.servicenow.com for the latest product documentation.


Web Services

1 Overview

A direct web service is available for any table in the system if you configure the correct access control. The supported format of the incoming message is document style literal XML SOAP documents (Document/Literal wrapped). To retrieve the direct web service WSDL description and XML schema for any given table, point to the relative URL of <tablename>?WSDL. For example, to retrieve the WSDL for the Incident table on the online demo system, use the following URL:

http://<instance name>.service-now.com/incident.do?WSDL

Notes:

  • When using Direct Web Services, input fields should not be left empty. If they are not required, they should be omitted entirely.
  • Default return for any query is limited to 250 records.

2 Available APIs

ServiceNow supports multiple APIs for direct web services.

3 Using Form Views to Limit/Extend Query Response

On occasion, there is a need to limit the number of field values being returned from a SOAP query (get or getRecords) invocation. Specifying a form view has the effects of:

  1. limiting the response elements to contain only the fields on the view
  2. specifying reference record field values from referenced fields eg. caller_id.email, this will cause the value of the caller's email to be returned in the SOAP response

To enable form views for SOAP queries, you may configure the property com.glide.soap.view to be the name of the view you wish to use for all SOAP query response (the default is soap_response). You may also specify the view name as a URL parameter sysparm_view=<view name> when making the SOAP call, for example:

https://<instance name>.service-now.com/incident.do?SOAP&sysparm_view=ess

If a specified view name does not exist, the default behavior is to respond with all fields.

4 Extended Query Parameters

The following parameters, when specified as elements of input parameters to SOAP query functions such as get, getKeys, and getRecords, has the additional behavior of filtering and modifying the results that are returned.

Note
Note: Extended query element names are preceded by two underscore characters.


Extended Query Parameter Description Example
__encoded_query Specify an encoded query string to be used in filtering the returned results. The encoded query string format is similar to the value that may be specified in a sysparm_query URL parameter. You may refer to the encoded query building example in the RSS feed generator examples.
 
<__encoded_query>active=true^category='hardware'</__encoded_query>

The example above illustrates a query for active records that have a category of 'hardware'

__order_by Instruct the returned results to be ordered by the specified field
<__order_by>priority</__order_by>
__order_by_desc Instruct the returned results to be ordered by the specified field, in descending order
<__order_by_desc>opened_date</__order_by_desc>
__exclude_columns Specify a list of comma delimited field names to exclude from the result set
<__exclude_columns>sys_created_on,sys_created_by,caller_id,priority</__exclude_columns>
__limit Limit the number of records that are returned
<__limit>100</__limit>
__first_row Instruct the results to be offset by this number of records from the beginning of the set. When used with __last_row has the effect of querying for a window of results. The results are inclusive of the first row number.
<__first_row>250</__first_row>
__last_row Instruct the results to be limited by this number of records from the beginning of the set, or the __start_row value when specified. When used with __first_row has the effect of querying for a window of results. The results are less than the last row number, and does not include the last row.
<__last_row>500</__last_row>
__use_view Specify a Form view by name, to be used for limiting and expanding the results returned. When the form view contains deep referenced fields eg. caller_id.email, this field will be returned in the result as well
<__use_view>soap_view</__use_view>

4.1 Perl Example - querying all incidents 5 records at a time

This example query queries all incidents, orders by the number field, and retrieves the first 5 records. You can easily extend this example to retrieve a set of predefined records, n number of records each query, simulating a windowed querying client. Using a windowed query mechanisms overcomes the default limitation of only getting a maximum of 250 records per query.

#!/usr/bin/perl -w

#use SOAP::Lite ( +trace =>; all, maptype => {} );
use SOAP::Lite;

# basic auth using the ITIL user
sub SOAP::Transport::HTTP::Client::get_basic_credentials {
   return 'itil' => 'itil';
}

# specify the endpoint to connect
my $soap = SOAP::Lite
    -> proxy('https://<instance name>.service-now.com/incident.do?SOAP');

my $method = SOAP::Data->name('getRecords')
    ->attr({xmlns => 'http://www.service-now.com/'});

# get all incidents with a window of 5, starting at row 0, and less than row 5 (total of 5 records)
my @params = ( SOAP::Data->name(__first_row => '0') );
push(@params, SOAP::Data->name(__last_row => '5') );
# the last row number can also be taken as the 'limit' offset by the starting first row

# order by the number field
push(@params, SOAP::Data->name(__order_by => 'number') ); 

my $result = $soap->call($method => @params);
print_fault($result);
print_results($result);

sub print_results {
  my ($result) = @_;

  my %keyHash = %{ $result->body->{'getRecordsResponse'} };

  my $i = 0;
  my $size = @{$keyHash{'getRecordsResult'}};
  for ($i=0; $i<$size; $i++) {
    my %record = %{$keyHash{'getRecordsResult'}[$i]};
    print "------------------------------ $i ----------------------------\n";
    foreach my $kk (keys %record) {
# print only the number of the incident
      if ($kk eq "number") {
        print "$kk=$record{$kk}\n";
      }
    }
  }
}

sub print_fault {
  my ($result) = @_;

  if ($result->fault) {
    print "faultcode=" . $result->fault->{'faultcode'} . "\n";
    print "faultstring=" . $result->fault->{'faultstring'} . "\n";
    print "detail=" . $result->fault->{'detail'} . "\n";
  }
}

5 Return Display Value for Reference Variables

When you query a record using a get or getRecords function the instance returns all fields associated with that record. The fields are often reference fields that contain a sys_id for a record on another table. Use one of these options if you want the display value for the field to be returned instead of the sys_id:

1. Add the property glide.soap.return_displayValue to your system properties, and every SOAP request will return a display value for a reference field.
2. Add the parameter displayvalue=true to your SOAP request URL, and SOAP requests with that parameter will return a display value for a reference field as a string, instead of the sys_id. The SOAP URL would look as follows:

https://<instance name>.service-now.com/incident.do?displayvalue=true&SOAP

3. Add the parameter displayvalue=all to your SOAP request URL, and SOAP requests with that parameter will return a display value for a reference field, in addition to the sys_id. The response element name for the display value field will be prefixed with dv_ such as dv_caller_id.

6 Retrieving Journal Entries

To get the contents of a journal field, make a second soap request against the sys_journal_field table to pull the appropriate journal records back for the record in question.

The URL for the WSDL would be in the following format

https://instance-name.service-now.com/sys_journal_field.do?WSDL

To retrieve the journal entries, you will first need to query the incident for its sys_id value and then supply it as the element_id value in a getRecords call. To sepcify records only for the "comments" field, specify the value "comments" for the element field. For example, a SOAP request would look like the following.

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sys="http://www.service-now.com/sys_journal_field">
   <soapenv:Header/>
   <soapenv:Body>
      <sys:getRecords>
         <element>comments</element>
         <element_id>9d385017c611228701d22104cc95c371</element_id>
      </sys:getRecords>
   </soapenv:Body>
</soapenv:Envelope>

7 Retrieving Choice Fields

To retrieve or set choice fields, use the choice Value not the Label. For example, if you want to retrieve a list of all closed incidents use the numerical value for Closed, which is 7 by default.

<state>7</state>

To see a list of choice values:

  1. Navigate to the form containing the choice field. For example, navigate to Incident > Open and select an incident.
  2. Right-click the choice value field and select Configure Dictionary (Personalize Dictionary in versions prior to Fuji). For example, configure the dictionary for the State field.
  3. From the Choices related list, note the value for the label you want to query. For example, note that the Closed choice has a value of 7.
    Choice values

8 Persisting HTTP session across all SOAP calls

Because ServiceNow uses stateless SOAP invocations, each SOAP call creates a new user session that persists until it expires. In circumstances when a SOAP client makes many calls in a short amount of time, you may want to re-use a single HTTP session for all SOAP calls. To create a single user session and re-use it for all inbound SOAP calls, develop your SOAP client following these guidelines:

  • Use a module like HTTP::Cookies to create a "cookie jar".
  • Save the cookies returned by ServiceNow after each request (handled automatically by HTTP::Cookies).
  • Re-send the cookies in the cookie jar with each subsequent request.
Note
Note: If you have enabled the session rotation high security setting, it will immediately invalidate the JSESSIONID returned from the server with the first response header. The second response includes a new JSESSIONID.


In perl, you can automatically save and send cookies with the following code:

use HTTP::Cookies;

#we want to store and re-send cookies
my $cookies = HTTP::Cookies->new(ignore_discard => 1);

my $soap = SOAP::Lite
    -> proxy('http://localhost:8080/glide/ecc_queue.do?SOAP');

#Set the cookie jar
$soap->transport->cookie_jar($cookies);

9 Compatibility for Clients Generated from WSDL

9.1 Specifying a Unique Namespace for each Table

The property glide.wsdl.definition.use_unique_namespace ensures that each table's Direct Web Service WSDL has a unique targetNamespace attribute. This property is true by default, which requires a table's Direct Web Service WSDL to use a targetNamespace value of http://www.service-now.com/<table name>. When false (or when the property is not present), all tables use the same targetNamespace value of http://www.service-now.com. Since all tables also share the same operation names, a Web Service client attempting to consume more than one ServiceNow Web Service would be unable to differentiate between requests between multiple tables. Using a unique targetNamespace value allows Web Services clients to distinguish requests between multiple tables.

For example, the DIrect Web Service WSDL for the incident table uses this targetNamepsace value.

<wsdl:definitions xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
  xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
  xmlns:tns="http://www.service-now.com/incident"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
  targetNamespace="http://www.service-now.com/incident">
<wsdl:types>
<xsd:schema elementFormDefault="unqualified"
  targetNamespace="http://www.service-now.com/incident">


9.2 Setting Namespace Requirements

ServiceNow's WSDL schema by default declares an attribute of elementFormDefault="unqualified". This attribute indicates whether or not locally declared elements must be qualified by the target namespace in an instance document. If the value of this attribute is 'unqualified', then locally declared elements should not be qualified by the target namespace. If the value of this attribute is 'qualified', then locally declared elements must be qualified by the target namespace.

However, this is incompatible with the way clients generated from WSDL (.NET, Axis2, webMethods, ect.) process the embedded schema, it removes the schema namespace as a result, making the web service response unparseable.

To overcome this compatibility issue, a boolean property called glide.wsdl.schema.UnqualifiedElementFormDefault is introduced. This property has the value of true by default, setting it to false will make clients generated from WSDL able to parse the return value of the web service invocation. You can modify this property using the Web Services properties page at System Properties > Web Services.

System property for elementFormDefault attribute

9.3 Allowing Duplicate Service Names

By default, service names from dynamically generated WSDL are unique and have the following format:

ServiceNow_<table name>

To allow duplicate service names, administrators can set the glide.wsdl.unique_service_name property to false. Create the property if it does not exist.

10 Enhancements

10.1 Fuji

Was this article helpful?
Yes, I found what I needed
No, I need more assistance