REST API Response Helper
Standardized functions for formatting and handling REST API responses with consistent error handling.
#rest-api #api #response-formatting #error-handling #scripted-rest #web-services
Script Code
JavaScript
1var RestResponseHelper = Class.create();
2RestResponseHelper.prototype = {
3
4 /**
5 * Create success response
6 * @param {object} data - Response data
7 * @param {string} message - Optional success message
8 * @param {number} statusCode - HTTP status code (default: 200)
9 * @returns {object} Formatted response
10 */
11 success: function(data, message, statusCode) {
12 return {
13 status: 'success',
14 code: statusCode || 200,
15 message: message || 'Request completed successfully',
16 data: data,
17 timestamp: new GlideDateTime().getValue()
18 };
19 },
20
21 /**
22 * Create error response
23 * @param {string} message - Error message
24 * @param {number} statusCode - HTTP status code (default: 400)
25 * @param {object} details - Additional error details
26 * @returns {object} Formatted error response
27 */
28 error: function(message, statusCode, details) {
29 return {
30 status: 'error',
31 code: statusCode || 400,
32 message: message || 'An error occurred',
33 error: details || {},
34 timestamp: new GlideDateTime().getValue()
35 };
36 },
37
38 /**
39 * Create validation error response
40 * @param {array} errors - Array of validation errors
41 * @returns {object} Formatted validation error
42 */
43 validationError: function(errors) {
44 return {
45 status: 'error',
46 code: 422,
47 message: 'Validation failed',
48 errors: errors,
49 timestamp: new GlideDateTime().getValue()
50 };
51 },
52
53 /**
54 * Create not found response
55 * @param {string} resource - Resource type (e.g., 'User', 'Incident')
56 * @param {string} identifier - Resource identifier
57 * @returns {object} Formatted not found response
58 */
59 notFound: function(resource, identifier) {
60 return {
61 status: 'error',
62 code: 404,
63 message: resource + ' not found' + (identifier ? ': ' + identifier : ''),
64 timestamp: new GlideDateTime().getValue()
65 };
66 },
67
68 /**
69 * Create unauthorized response
70 * @param {string} message - Optional message
71 * @returns {object} Formatted unauthorized response
72 */
73 unauthorized: function(message) {
74 return {
75 status: 'error',
76 code: 401,
77 message: message || 'Unauthorized - Authentication required',
78 timestamp: new GlideDateTime().getValue()
79 };
80 },
81
82 /**
83 * Create forbidden response
84 * @param {string} message - Optional message
85 * @returns {object} Formatted forbidden response
86 */
87 forbidden: function(message) {
88 return {
89 status: 'error',
90 code: 403,
91 message: message || 'Forbidden - Insufficient permissions',
92 timestamp: new GlideDateTime().getValue()
93 };
94 },
95
96 /**
97 * Create paginated response
98 * @param {array} data - Array of results
99 * @param {number} page - Current page number
100 * @param {number} pageSize - Results per page
101 * @param {number} total - Total number of results
102 * @returns {object} Formatted paginated response
103 */
104 paginated: function(data, page, pageSize, total) {
105 var totalPages = Math.ceil(total / pageSize);
106
107 return {
108 status: 'success',
109 code: 200,
110 data: data,
111 pagination: {
112 page: page,
113 pageSize: pageSize,
114 totalResults: total,
115 totalPages: totalPages,
116 hasNext: page < totalPages,
117 hasPrevious: page > 1
118 },
119 timestamp: new GlideDateTime().getValue()
120 };
121 },
122
123 /**
124 * Format GlideRecord as REST response
125 * @param {GlideRecord} gr - GlideRecord object
126 * @param {array} fields - Fields to include (optional, defaults to all)
127 * @returns {object} Formatted record object
128 */
129 formatRecord: function(gr, fields) {
130 if (!gr || !gr.isValidRecord()) {
131 return null;
132 }
133
134 var record = {
135 sys_id: gr.sys_id.toString(),
136 sys_created_on: gr.sys_created_on.toString(),
137 sys_updated_on: gr.sys_updated_on.toString()
138 };
139
140 if (fields && fields.length > 0) {
141 // Include only specified fields
142 fields.forEach(function(field) {
143 if (gr.isValidField(field)) {
144 record[field] = gr[field].toString();
145 record[field + '_display'] = gr[field].getDisplayValue();
146 }
147 });
148 } else {
149 // Include all fields
150 var fieldNames = gr.getFields();
151 for (var i = 0; i < fieldNames.size(); i++) {
152 var fieldName = fieldNames.get(i).getName();
153 record[fieldName] = gr[fieldName].toString();
154
155 // Add display value for reference fields
156 if (gr[fieldName].getReferenceTable()) {
157 record[fieldName + '_display'] = gr[fieldName].getDisplayValue();
158 }
159 }
160 }
161
162 return record;
163 },
164
165 /**
166 * Format multiple GlideRecords as array
167 * @param {GlideRecord} gr - GlideRecord with query results
168 * @param {array} fields - Fields to include (optional)
169 * @param {number} maxResults - Maximum results to return
170 * @returns {array} Array of formatted records
171 */
172 formatRecords: function(gr, fields, maxResults) {
173 var records = [];
174 maxResults = maxResults || 1000;
175 var count = 0;
176
177 while (gr.next() && count < maxResults) {
178 records.push(this.formatRecord(gr, fields));
179 count++;
180 }
181
182 return records;
183 },
184
185 /**
186 * Validate required fields in request
187 * @param {object} request - Request object
188 * @param {array} requiredFields - Array of required field names
189 * @returns {object|null} Validation error response or null if valid
190 */
191 validateRequired: function(request, requiredFields) {
192 var errors = [];
193
194 requiredFields.forEach(function(field) {
195 if (!request[field] || request[field] === '') {
196 errors.push({
197 field: field,
198 message: 'Field "' + field + '" is required'
199 });
200 }
201 });
202
203 if (errors.length > 0) {
204 return this.validationError(errors);
205 }
206
207 return null;
208 },
209
210 /**
211 * Handle exception and return error response
212 * @param {Error} exception - Exception object
213 * @param {string} context - Context where error occurred
214 * @returns {object} Formatted error response
215 */
216 handleException: function(exception, context) {
217 var errorMsg = exception.message || exception.toString();
218
219 gs.error(context + ': ' + errorMsg);
220
221 return {
222 status: 'error',
223 code: 500,
224 message: 'Internal server error',
225 error: {
226 context: context,
227 details: gs.getProperty('glide.rest.verbose_errors') === 'true' ? errorMsg : undefined
228 },
229 timestamp: new GlideDateTime().getValue()
230 };
231 },
232
233 type: 'RestResponseHelper'
234};
How to Use
1. Create a new Script Include named 'RestResponseHelper'
2. Leave 'Client callable' unchecked
3. Copy the code above
4. Use in Scripted REST APIs:
var helper = new RestResponseHelper();
// Success response
response.setBody(helper.success({user: userData}, 'User found'));
// Error response
response.setBody(helper.error('Invalid user ID', 400));
// Not found
response.setBody(helper.notFound('Incident', incNumber));