Getting Started – XService API


This tutorial will help you start using the Xservice search API.

Usually you will use the search API in order to build your own UI (user interface) using your own specific look & feel.

This tutorial will let you download a ready-to-go application for searching your primo data using an interface built upon the XService API.

This is useful as a starting point for anyone interested in building his own Primo site.

The files downloaded can be used in the following ways:

  1. Examine the code to understand the concepts of how the search API can be used.
  2. Use as a starting point for your site – Add, remove or modify the
    supported functionality, and change the styling (CSS) of the site.


Use the following link: here to download the ZIP file including the application

The application

Important note: The styling of this demo is not intended to be a production ready.
I am surely not a web master and have very little knowledge with CSS.
The idea in this demo is to demonstrate how to access and parse the data coming
back from the API.
It is left for you, to modify and decide how to style and present the data.

The opening page

Only a search box exists and a language drop down:

Results + facets display

After clicking search the results appear:

Record details

Clicking a record’s title, will display some of it’s details on the right pane:


The site is built using the following technologies:


2) JavaScript

3) CSS

If you have knowledge with the above you will be able to modify the code for your own needs.

Otherwise, you can still use this as a demo. With no programing knowledge at all you will be able run it and query your local Primo.

Files included in the project

  1. index.html – the 1 and only HTML file. This file includes all the logic and scripting parts used by this project
  2. js (directory) – includes in it 2 directories:
    1. libs – currently includes the jquery library (jquery-1.9.1.js),
      and an additional library to enable pagination (jquery.simplePagination.js).
    2. i18n – holds the translations for the different elements on the page.
      Currently it includes translations for English and French.
      The file structure is self-explanatory and can be added with additional languages.
  3. Images (directory) – includes currently 1 image
  4. css (directory) – includes the css files used in this project

Register your IP

Before trying to run the application you should make sure your IP address is registered in your Primo system.

This application is dependent on Primo’s XService API and in order for it to work you must register your IP in the “and XS IP” mapping table.

When your IP is not registered you will have no access to Primo’s XService.

NOTE: After entering your IP in the mapping table, you must deploy
“All client IP ranges (WS and XS IP mapping table)” that exists in the deploy screen.

Identifying your IP address

Below are two possible options (more exist)

  1. From the computer that is going to run this application, open a browser and search in Google for “What Is My IP”.
  2. If you have access to the Primo FE machine – Execute the URL in the step below. You will receive a negative response saying you are not authorized.

Now enter the log directory (fe_log) and view the library_server.log, look for a line such as:

[c-WsXsIpFilter] [O -(2000001,2160632,null)] –
Unauthorized access level:(2000001,2160632,null) for ip:

The IP at the end of the line, is the IP you need to register.

Checking your IP registration is working

You can use the following URL in your browser to check if the XService is working:

http://<your primo domain>/PrimoWebServices/xservice/search/brief?institution=<primo institution>&indx=1&bulkSize=10&query=any,contains,science

(fill in the two place holders (primo domain and institution))

If you get a result displaying on the page, it is working.

If you get a result with status 403 (access denied), something is wrong with the IP registration.

There is no point continuing if the above URL is not working for you.

Running the application for the first time

In order to get the application working, you must edit the index.html page and modify 2 lines:

host : “<your primo domain>”,

institution: “<institution code>”,

(For example, these 2 lines can look like:

host : “primodemo:1701”,

institution: “VOLCANO”,)

host – You must modify the host value to the domain you are working against
(this will be the domain used in the step above for checking your IP).
Note, the host might include the port number (for example:

institution – modify the value to hold your institution code, as done in the step above, for checking your IP.

Once these 2 values have been set, save the index.html file, and then just double click it, so it will open in your browser.

That’s it!!! The application is ready to be used.

Understanding the application’s structure

The index.html page holds an empty HTML structure which gets populated once the “search” button is clicked.

The structure looks like this:

Each square in the image above is represented by a <div> element.

<div id="searchbox" style="float: top">

    <input id="search" type="text" placeholder="Type here" value="book">

    <input type="button" value="Search" onclick="searchRequest.reset();search()">


<div id="pagination" ></div>

<div id='body'>

  <div id="facets" style="float: left; width: 10%;"/>

       <div id="totalResults" style="padding-bottom:10px;"/>
       <div id="facetsbreadcrumbs"/>
       <div id="results"/>

  <div id="details"/> 


Understanding the XService response

The default result coming back from the XService is in the XML format.

As the Javascript language can parse and handle JSON objects easily, this application we call the XService, requesting the results to be returned as JSON (this is done by adding to the URL, the parameter: &json=true).

All explanations below will be done using XML examples (although application uses JSON)  as it is more structured an easier to understand.

The response coming back from the XService is called a “Result Set”.

The result set is built from 3 main parts:

  1. Did you mean – not used in this application.
  2. Facets
  3. Records (a list of PNX records)

Below is a look at the returned XML response when the facets (FACETLIST) and the records section (DOCSET) are collapsed (the did you mean (QUERYTRANSFORMS) is empty in this example)

The facets section contains all the different facet types and values.

<sear:FACET NAME="lcc" COUNT="20">
    <sear:FACET_VALUES KEY="K - Law." VALUE="321"/>
    <sear:FACET_VALUES KEY="U - Military science." VALUE="112"/>

The DOCSET section includes a list of PNX records.

Each PNX will look like this:

<sear:DOC ID="204765>
          <title>The World Book dictionary</title>

Understanding the code

As said above, the application comes with an empty template that gets populated once data is ready to be displayed.

There is a javascript function responsible for populating each different section in the template.

The application uses a searchRequest Object, to keep and maintain data entered by the user.

Such data can be: the chosen facets, the interface locale and the query performed.

The searchRequest object looks like this:

searchRequest = {

                host : "",

                institution: "VOLCANO",


                facets: [],




                sort:'', //relevance

                reset: function() {this.facets = []; = 1}


The above object will get populated once links/buttons are clicked.

Then a javascript function will be called to perform the required task according to data in the searchRequest object.

The search() function

This function is called for the following events:

  1. Search button was clicked (or the “enter” key was pressed)
  2. Facet was clicked
  3. Page number has been clicked (changed)
  4. Sort has been changed
  5. Language has been changed

The function’s flow:

  1. Extract the query term from the search box, store it in the searchRequest object.
  2. Set the locale chosen (set the i18n javascript library)
  3. Calculate the record number to start displaying the results from (according to the selected page number)
  4. Append to the query, any facet that has been chosen
  5. Perform the search by executing an XService call
    (this is done using AJAX so the request is done in the background. Once the results are ready the
    parseResponse() function will be called causing the data on screen to be presented/refreshed).

The parseResponse() function

This is the main function doing all the work of presenting the data returned.

This function is called when results return back from the XService call.

This function will populate each of the different panes in the HTML template:

  1. Facets
  2. Record results
  3. Pagination
  4. Facet breadcrumbs

Before populating each pane, the function will first empty the content from the relevant pane, and then populate it.

The emptying of a pane is done like this (this empties the facets pane):


Then the population is done like this:

$(“#facets”).append(<HTML content>);

Facets parsing

The facets reside in the following path:



This piece of code below, scans under this path all the facets, and for each facet type, it calls the method: getFacetValues(),
which will create an HTML list for the first 5 values, for this facet type, for Example for each type you will end up with:


  <ul class=’muted’>

     <li>eng (10)</li>

     <li>fre (10)</li>

     <li>heb (10)</li>



Below is the real code doing the work:


          function(key, record) {                          

                var facetValues = getFacetValues(record['@NAME'], record["FACET_VALUES"]);

                if (facetValues == "") return;


                       "<div>" + I18n.t(record['@NAME']) +                        

                       "<ul class='muted'>" +  facetValues + "</ul>" +                    



Record parsing

The records reside in the following path:


Below is the code treating the records and displaying them.

We basically scan each record, and extract from it the relevant fields to be presented.

Below is the beginning of the code scanning the records:

var records = data["SEGMENTS"]["JAGROOT"]["RESULT"]["DOCSET"]["DOC"];

   if (!(records instanceof Array)) {records = [records];} //only 1 record returned               
               function(index, record) {
                   var pnx = record;


What else can be done

In this demo there is no treatment to the data relevant to the delivery manager, data such as:

  1.  Availability
  2. Thumbnails
  3. Libraries
  4. Back links, full text links, …

Adding links and thumbnails should be very easy.

Just add an additional section to the parseResponse() function, by scanning the relevant paths in the response.