GlideRecord or GlideQuery? That's the question.

GlideQuery is a server-side object for CRUD operations in ServiceNow supported in Orlando and later versions. Behind the scenes, it uses GlideRecord but with smart defaults that often will cause generally problems. This API works together with the Stream and Optional APIs in a builder pattern where the method calls chain together, each method building on the returned result of the previous method. Use methods to define the attributes of the query. The methods do not execute until you call a terminal method, a method that returns a query result, allowing you to define the requirements of the query before executing it.


GlideQuery is a modern, expressive, and safer interface to the Now platform. You use it where you might typically use server-side GlideRecord. As a wrapper over GlideRecord, it can catch mistakes earlier in the development process and simplify many queries. You can find the documentation for GlideQuery


How to install this without Software Asset Management Pro?


var plugins = [];
plugins.push('com.sn_glidequery');
var main = new GlideMultiPluginManagerWorker();
main.setPluginIds(plugins);
main.setProgressName("Plugin Installer");
main.setBackground(true);
main.start();

This GlideQuery follows three guiding principles:

  • Fail Fast

  • Be JavaScript

  • Expressive

Here are some considerations:

  • Performance

  • Failing Fast

  • Improving the feedback loop

  • Field Checking

Performance

With business rules disabled here's how GlideQuery stacks up to GlideRecord. One advantage of using GlideQuery here is that it performs a set of validation checks before executing the query. For example, if the priority, short_description, or opened_at fields didn’t exist, GlideQuery would throw an error message (with a readable stack trace!) explaining the problem.


GlideQuery vs. GlideRecord

GlideQuery is Server script API consists of 2 global script includes:

  • GlideQuery, to which we can have a look (nonprotected)

  • GlideQueryEvaluator, which is protected, therefore it is not possible to have a look at it.

It is said that it uses GlideRecord under the hood, probably inside the GlideQueryEvaluator script. It also replaces GlideAggregate in some cases (in particular for counting records) and it is 100% JavaScript.


So it will not replace GlideRecord, but it proposes an additional layer on the top of it, that offers several benefits to the developers. Mainly it should reduce the likelihood of errors and mistakes when manipulating GlideRecord and make its usage clearer and easier.


Here's a GlideRecord script with a problem - by default if a field name is wrong in GlideRecord, it queries everything. In GlideQuery, this will fail and not execute on error.


READING MULTIPLE ROWS

new GlideQuery('task')
    .where('priority', 1)
    .select('short_description', 'opened_at')
    .forEach(function (task) {
 gs.info('Task "' + task.short_description + '" was opened at ' + task.opened_at);
    });


USING SELECT AND STREAM

new GlideQuery('sys_user')
    .select('first_name')
    .forEach(function (user) {
 gs.info(user.first_name);
   });

READING A SINGLE RECORD


// Find user if they exist, otherwise return user with first_name 'Nobody'
var user = new GlideQuery('sys_user')
    .where('last_name', 'Luddy')
    .selectOne('first_name')
    .orElse({ first_name: 'Nobody' });

// Find user, otherwise throw an Error that the user couldn't be found
var user = new GlideQuery('sys_user')
    .where('last_name', 'Luddy')
    .selectOne('first_name')
    .get(); // this method can throw if no record is found

// Does a given user exist? Assign boolean to userExists
var userExists = new GlideQuery('sys_user')
   .where('last_name', 'Luddy')
    .selectOne('first_name')
    .isPresent();

What About Scopes?

One final important sidenote: GlideQuery is a script that includes (global scope), therefore when used within a scoped app, it (as well as Stream and Optional) must be prefixed with the “global” scope.

new global.GlideQuery('sys_user')

Conclusion

GlideQuery is designed to catch mistakes early in the development cycle and behave more like a regular JavaScript API. GlideQuery has a fluent interface, which requires you to chain your method calls together.


GlideRecord going away? The GlideQuery seems to be just a wrapper to allow chain-able calls to query the data. Maybe as the Now Experience comes up this will be used more in that but I don't think so. I think this is just a wrapper some teams made to make their code look better.