Datadog

Datadog Expertise

RapDev is a Datadog Premier Partner focused on accelerating our customers’ time to value.
600
Implementations
110
US-Based Engineers
68
Datadog Certifications

Security & Managed SOC

Quickly and seamlessly implement Cloud SIEM, ASM, SCA, and Cloud Security Posture Management to power a modern DevSecOps strategy

Incident Management

Transform data into high-confidence, actionable incidents using AI-driven detection, clear ownership models, and automated remediation

Marketplace Integrations

RapDev is proud to offer more Datadog Marketplace integrations than any other partner

ServiceNow

ServiceNow Expertise

RapDev is a ServiceNow Elite partner focused on helping you drive business outcomes with the ITx suite.
4.7
CSAT Score
136
Product Line Certs.
67k
AI Agents Discovered

Agentic AI & AI Governance

Deploy and scale production-ready agentic AI to automate workflows and accelerate ServiceNow outcomes

Enterprise Architecture

Connect your technology landscape to business strategy to optimize investments, reduce risk, and accelerate modernization

ServiceNow Store

Leverage RapDev’s certified apps and AI Agents to expedite operations on the Now Platform
Blog
Company

About RapDev

RapDev is powered by a team of experienced, U.S. based engineers focused on redefining service operations through AI, automation, and modern observability.

Join the RapDev team

Our no-frills approach to collaborating is what allows us to deliver the best. Our team is growing and we’re looking for the best in the game.

Press

Latest news and announcements from RapDev

Events & Webinars

From hands-on workshops to industry-leading conferences

Resources

Back to blog

Crafting Smart Objects in ServiceNow

Replace util scripts with smart objects in ServiceNow by adding context, encapsulating logic, and improving code design

X

min read

April 15, 2025

Rob Witty

How often have we seen a script include with “Util” in the name? “Util” is really an abbreviation for “bucket of stuff.”  They look like this, but usually not as organized: 

“Util” script includes, like buckets, are dumb. They’re just a container to collect functions–sort of like a junk drawer. If there’s any relationship between functions, then something outside the bucket better know that, because the bucket’s not going to help you. 

What if we created smart objects instead of buckets?

What is a smart object? 

We might think that a “smart object” knows a lot of stuff about a great many things. But that would violate the Separation of Concerns principle–a fundamental principle of good software design. So by “smart object” I mean an object that concerns itself with one thing. That “thing” is usually a real thing in your system, like a Purchase Order. The smart object will know about a purchase order’s data and the logic required to service that data. A smart object hides complexity from, and provides service functions to, the rest of the system for its “one thing.”

Here’s an example from an OOB object called ProcurementUtils. This object provides a lot of different functions, doing different things. Notice how you have to provide the PO number for each function. Why?  Because the util bucket has no persistent context. And because of this, the function names must provide some context in order to know we’re dealing with a PO and not one of the many other records the object may handle. So we get function names like this: 

Let’s imagine that we crafted a smart object instead.  Let’s call it PurchaseOrder. It’s not a bucket of functions around the PO. Rather, we treat this smart object as if it were a PO.  We instantiate our PurchaseOrder object with a PO sysid only once. Thereafter, all functions pertain to that PO. Notice how this provides context and simplifies the code. Here’s an example of the same functions using our smart PO object:

Better!  And you don’t have to pass the PO number for every function because the smart object has context. Nice. 

But there’s more benefit here than just simplified function names and less argument-passing. Consider our “utils” object, ProcurementUtils.  Anything that invokes it must have specific knowledge about purchase orders and their relationships to other tables. As a consequence, knowledge about Purchase Orders is dispersed across the platform.  

By contrast, our smart object encapsulates knowledge about PO’s into one place–itself.  If anything in the system needs to engage a PO process, they need only ask the PurchaseOrder object. When it comes to a PO, it’s the smartest object in the system. We want it to be smart, so other components in the system don’t have to be

Let’s consider an example. 

Unfortunately, most ServiceNow script includes are “util” buckets. But this won’t stop us from creating smart objects for our scoped apps and custom solutions, yes? Let’s suppose we’re building a scoped app that automates server patching. Here are some guidelines for creating a smart object. 

  1. Create an object that represents an identifiable “thing” in the system. Typically, this means a table. In our new app, we have a table called Patch Definition, where we store the data for what constitutes a patch.  So we’ll create an object called PatchDefinition
  1. Upon instantiation, a smart object (usually) represents a single row in a table.  So in our example, the instantiation would look like this: 

var patchDef = new PatchDefinition(patchId);

The variable patchDef now represents a row on our Patch Definition table. Any data you need to consume from the row, any work you need to do with the row, any updates you need to make to the row–can all be made by function calls to the patchDef object we just instantiated. Here are some examples: 


patchDef.isScheduledForDeployment();
patchDef.checkForLatestUpdates();
patchDef.isApproved();
patchDef.addToChangeRequest(aChangeRequest);
var serverList = patchDef.getTargetServers();
  1. What if we want to create a new Patch Definition row

var patchDef = new PatchDefinition(); // pass nothing.
patchDef.setTargetServers(serverList);
patchDef.setPatchMods(modificationList);
patchDef.setTargetInstallDate(someDate);
patchDef.update();

Notice this script snippet doesn’t have to know what table is involved, or what fields to update, or whether the data passes edits, etc. All those details are hidden, known and performed by the smart object. Thus, knowledge about a patch definition is not scattered throughout our system. It’s in one place. Nice. 

Let’s think about software design. 

Crafting smart objects aligns with industry-acknowledge software design principles, like Separation of Concerns and the Single Responsibility Principle.  Within the ServiceNow environment, we don’t often pause to ponder software design. It’s so easy to just code snippets of logic here and there. And for simple applications, this works well. But when building more complex and nuanced applications, these principles serve us well and reward us with apps that are easier to maintain, grow, and scale.  

Interested to learn more? Reach out to chat@rapdev.io.