Skip to content

zhmur/servicenow-guides

Repository files navigation

Best practicies

Preread

  1. Performance considerations
  2. ServiceNow Custom Table Guide

Fields

Naming convention

  1. Separate individual words with underscore. Example: "u_first_name".
  2. Use plural name (and label) for a slushbacket (list collector) fields and variables. Examples: "u_regions", "u_countries".
  3. Capitalize only first letter of a field label. Abbreviations can be considered as an exception. Examples: "Due date", "JWT token".
  4. Do not use generic type names for a fields. Name should indicate field purpose. Example: "u_string", "u_number".
  5. Keep field name length reasonably short, but use only well understood abbreviations.

Best practices

  1. Use sys_dictionary.comments (add this field on the dictionary form if missing) field to describe purpose of the field.
  2. Always check where field is defined in the tables hierarchy during dictionary changes. You may impact a lot more tables than you planned.

System properties

Naming convention

Format: <company>.<process|interface|system|integration>.[subprocess].<property_name>

Examples below present preferred names and not for system properties (now - company prefix):

  • now.sam.mass_deployment_limit (ok, sam - software asset management)
  • now.sn.user_story.assignment_group.default (not ok, what is sn|user_story, default_assignment_group)
  • now.demand_factory.default_group_id (ok)
  • now_factory_it_integartion_pass (not ok, totally WRONG!)
  • integration.opentext.incident.user (not ok, missing company prefix, what user?)

Other considerations

  1. Explanatory description is mandatory, where system property is used and how.
  2. If system property holds a temporary value, then describe where to obtain a new one e.g. an access token, password, integration endpoint.
  3. Default assignment group in system property - is a bad practice, better option is a template, dictionary override, dictionary setting.
  4. Creating a new record with default field values must use a template, NOT a system property.

Syntax, names, labels, defaults

  1. Follow Update sets naming convention.
  2. Use singular name for tables. Example: "incident", "task".
  3. Capitalize each word of a table label. Examples: "Catalog Task", "Support Group".

Programming, code, style

  1. Use ES5 Airbnb JavaScript Style Guide() { for all JavaScript code.
  2. By default use full table name for GlideRecord class variables. Example: var incident = new GlideRecord('incident');.
  3. Use "ID" suffix for variables containing GlideRecord sys_id in scripts. Example: var userID = '';.
  4. Do not use global business rules as they have no conditions or table restrictions and as a result load on every page in the system.
  5. Do not use gs.sleep. It does not release session and blocks thread (occupies Scheduler Worker). As a result instance may run out of worker threads for other jobs.
  6. Do not meet concurrent workflow paths without "Join" activity. Doing so will cause subsequent activities execute twice.
  7. Logic inside business rule should be simple. Complex logic should be incapsulated in script include(s).
  8. A script include method should tend to be context independent. Calls to current, previous, worklow.scratchpad, current.variables objects should be exceptional. Passing GlideRecord through parameter or constructor is okay.
  9. Use gs.debug and gs.info instead of gs.log as it doesn't work in a scoped apps. If you want to use it in Global scope always specify "source" parameter: gs.log('Message', 'Source');. This will help to identify origin of the messages in system log.
  10. If a business rule, workflow, scheduled job/whatever script updates visible field on a record (especially task.state), always put a comment/work note into the target record which allows to quickly identify update source. Following this practice is especially important for one-off activities (for example, data cleanups/manipulations), so leave as much breadcrumbs as possible (for example, pass update reason as GlideRecord.update method parameter incident.update('TASK2574355'); to reflect it in the audit record).
  11. Never use direct "Table API" for integrations, use "Import Set API" instead. It enables better control of imported data and source indentification.
  12. Before changing a code, be sure it is the same as in production and not changed by others. Be aware not to capture and transfer changes made by others.
  13. When using current.setAbortAction(true); in business rules, always add current.setWorkflow(false); as otherwise it won't stop remaining BR to run in sequence.

Maintenance

  1. Put old item name to sc_cat_item.meta field in case of catalog item rename. If item was used in production at least once in last 3 months. For popular items consider keeping old name in the sc_cat_item.name for some time. So that users will have time to adapt.
  2. Never delete obsolete records, use archive instead.

Deployments

  1. Use batch update sets whenever possible. Even if you have only 2 update sets for commit, go ahead and select one of them as a parent.
  2. Update sets commits, apps installations (updates) causes instance flash cache (equal to cache.do).
  3. Do not back out update sets unless absolutely necessary.

Patterns

  1. Avoid custom states introduction for OOB task table extends. Address business requirements using substates.
  2. Never allow deletion of records for end users (not platform administrators). Use "active" field instead.
  3. Use templates to store static (default) values in case you need to create/update incident, task etc. Template can be exposed for end users. If template can't be used (for example, you want to submit request using Service Catalog API), create system property and put JSON with static values there.
  4. Put meaningful information in task.short_description, especially for generic tasks. This rule is applicable for both: when you are programmatically generating it or when you are creating task by yourself. Remember! Main purpose is to quickly identify correct task from the list.
  5. Consider a script include for each table to implement data manipulations: creating, modifying, querying data.
  6. Use ";" (semicolon) as separator if you need to show list of usernames in a string. For example, pattern "<last name>, <first name>" is very popular one for large enterprises because surname is more selective then a name. Example: "Zhmur, Artur; Dureiko, Sergey".
  7. Place "Number" or reference name field top left on the form layout; first on the list layout.
  8. Use email subaddressing to give out alternatives to your instance email address. Format: <email>+<tag>@<domain>. The text of the tag can be used to configure simple and reliable filter for inbound email action. Example: dev100824+security_incident@service-now.com.
  9. Extend Import Set API response with additional attribute using Transform Map script (sys_transform_map.script): response.<attribute> = '';.
  10. Use GlideElement.nil (in case of GlideRecord) or standard JS to check if variable/attribute is empty or not. Do not use JSUtil.nil as it is not available in scoped apps. gs.nil usage is acceptable but not recommended for consistency reasons.

Performance

  1. Specify fields to return by a database view. Include only fields which you need.
  2. Check widgets performance using ServiceNow provided script.
  3. Be aware that platform executes workflow activities sycnhronously after a manual action (e.g., approval, item submission on SP). This can significantly impact form submission time. Make sure that synchronously executed code is fast or place 1 second Timer after manual step to make the rest of the workflow async (non-interactive).
  4. GlideRecord.getRowCount() vs GlideAggregate. General preference is to use GlideAggregate to get count of the records in a query. Though, the benefits of GlideAggregate are visible on large datasets i.e. when query result set is big (aka > 10k records).

Tricks & tools

  1. Use "- b" + Enter in the Navigator filter to quickly find and open "Scripts - Background".
  2. Use SN Utils browser plugin. Features: node switching, technical field names and many more.
  3. In navigation menu use uppercase "table_name.LIST" to open a list in a separate browser tab.
  4. Cancel all running transactions under your account (only on your current cluster node): https://<instance>.service-now.com/cancel_my_transaction.do.
  5. Override (only if necessary, this may hit instance from performance perspective) list row count per page: https://<instance>.service-now.com/<table>_list.do?sysparm_force_row_count=100.
  6. Open large tables (for example sys_audit) without data: https://<instance>.service-now.com/<table>_list.do?sysparm_filter_only=true.
  7. Diagrams drawing (OSS): diagrams.net, Excalidraw.

Further reading

  1. High Performance Browser Networking
  2. You Don't Know JS: Up & Going - Chapter 2: Into JavaScript
  3. 97 Things Every Programmer Should Know
  4. Blog: snhackery
  5. Blog: SN Pro Tips
  6. Blog: snow underground
  7. Blog: jace.pro

About

Different ServiceNow related guidelines

Topics

Resources

Stars

Watchers

Forks