UNPKG

6.62 kBJavaScriptView Raw
1/**
2 * @file Defines the BaseResponse class.
3 *
4 * @author Luke Chavers <luke@c2cschools.com>
5 * @author Kevin Sanders <kevin@c2cschools.com>
6 * @since 5.0.0
7 * @license See LICENSE.md for details about licensing.
8 * @copyright 2017 C2C Schools, LLC
9 */
10
11"use strict";
12
13const BaseClass = require( "@corefw/common" ).common.BaseClass;
14
15/**
16 * This is the base class for all API responses.
17 *
18 * @abstract
19 * @memberOf Response
20 * @extends Common.BaseClass
21 */
22module.exports = class BaseResponse extends BaseClass {
23
24 /**
25 * Stores a reference to the {@link Request.Request} object that this
26 * object is being used to respond to.
27 *
28 * @public
29 * @type {Request.Request}
30 * @default null
31 */
32 get request() {
33
34 const me = this;
35
36 return me.getConfigValue( "request", null );
37 }
38
39 set request( /** Request.Request */ val ) {
40
41 const me = this;
42
43 me.setConfigValue( "request", val );
44 }
45
46 /**
47 * A reference to the current execution context.
48 *
49 * @public
50 * @type {ExecutionContext.BaseExecutionContext}
51 * @readonly
52 */
53 get context() {
54
55 const me = this;
56
57 if ( me.request === null ) {
58
59 return null;
60 }
61
62 return me.request.context;
63 }
64
65 /**
66 * The data portion of the response.
67 *
68 * @public
69 * @type {Object}
70 * @default {}
71 */
72 get data() {
73
74 const me = this;
75
76 return me.getConfigValue( "data", {} );
77 }
78
79 set data( /** Object */ val ) {
80
81 const me = this;
82
83 me.setConfigValue( "data", val );
84 }
85
86 /**
87 * The endpoint that is responding.
88 *
89 * @public
90 * @type {?Endpoint.BaseEndpoint}
91 * @default null
92 */
93 get endpoint() {
94
95 const me = this;
96
97 return me.getConfigValue( "endpoint", null );
98 }
99
100 set endpoint( /** ?Endpoint.BaseEndpoint */ val ) {
101
102 const me = this;
103
104 me.setConfigValue( "endpoint", val );
105 }
106
107 /**
108 * The operationId (class name) of the endpoint that is responding.
109 *
110 * @public
111 * @type {?string}
112 * @default null
113 */
114 get operationId() {
115
116 const me = this;
117
118 if ( me.endpoint === null ) {
119
120 return null;
121 }
122
123 return me.endpoint.operationId;
124 }
125
126 /**
127 * The name of the service in which the responding endpoint resides.
128 *
129 * @public
130 * @type {?string}
131 * @readonly
132 */
133 get serviceName() {
134
135 const me = this;
136
137 if ( me.endpoint === null ) {
138
139 return null;
140 }
141
142 return me.endpoint.serviceName;
143 }
144
145 /**
146 * The version of the service in which the responding endpoint resides.
147 *
148 * @public
149 * @type {?string}
150 * @readonly
151 */
152 get serviceVersion() {
153
154 const me = this;
155
156 if ( me.endpoint === null ) {
157
158 return null;
159 }
160
161 return me.endpoint.serviceVersion;
162 }
163
164 /**
165 * The primary model of the responding endpoint.
166 *
167 * @public
168 * @type {?string}
169 * @default null
170 */
171 get primaryModel() {
172
173 const me = this;
174
175 return me.getConfigValue( "primaryModel", null );
176 }
177
178 // noinspection JSUnusedGlobalSymbols
179 set primaryModel( /** ?string */ val ) {
180
181 const me = this;
182
183 me.setConfigValue( "primaryModel", val );
184 }
185
186 /**
187 * The status code of this response, which should correlate to an
188 * Http status code.
189 *
190 * @public
191 * @type {number}
192 * @see https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
193 * @default 200
194 */
195 get statusCode() {
196
197 const me = this;
198
199 return me.getConfigValue( "statusCode", 200 );
200 }
201
202 set statusCode( /** number */ val ) {
203
204 const me = this;
205
206 me.setConfigValue( "statusCode", val );
207 }
208
209 /**
210 * The body of the response.
211 *
212 * @public
213 * @type {Object}
214 * @readonly
215 */
216 get body() {
217
218 const me = this;
219
220 return me._createResponseBody();
221 }
222
223 /**
224 * The body of the response, serialized into a JSON string.
225 *
226 * @public
227 * @type {string}
228 * @readonly
229 */
230 get strBody() {
231
232 const me = this;
233
234 return JSON.stringify( me.body );
235 }
236
237 /**
238 * The http headers that should be included in the response if the client
239 * is invoking this endpoint by way of an http API or proxy.
240 *
241 * @public
242 * @type {Object}
243 * @readonly
244 */
245 get headers() {
246
247 const me = this;
248
249 return {
250 "x-series-uuid": me.seriesId,
251 };
252 }
253
254 /**
255 * The seriesId (which is a UUID) for this response. This is mirror/alias
256 * of {@link ExecutionContext.BaseExecutionContext#seriesId}.
257 *
258 * @public
259 * @type {?string}
260 * @readonly
261 */
262 get seriesId() {
263
264 const me = this;
265
266 if ( me.context === null ) {
267
268 return null;
269 }
270
271 return me.context.seriesId;
272 }
273
274 /**
275 * The requestId (which is a UUID) for this response. This is mirror/alias
276 * of {@link ExecutionContext.BaseExecutionContext#requestId}.
277 *
278 * @public
279 * @type {?string}
280 * @readonly
281 */
282 get requestId() {
283
284 const me = this;
285
286 if ( me.context === null ) {
287
288 return null;
289 }
290
291 return me.context.requestId;
292 }
293
294 /**
295 * The api stage for this response. This is mirror/alias of
296 * {@link ExecutionContext.BaseExecutionContext#apiStage}.
297 *
298 * @public
299 * @type {?string}
300 * @readonly
301 */
302 get apiStage() {
303
304 const me = this;
305
306 if ( me.context === null ) {
307
308 return null;
309 }
310
311 return me.context.apiStage;
312 }
313
314 /**
315 * Indicates whether or not this response represents an error.
316 *
317 * @public
318 * @type {boolean}
319 * @default false
320 */
321 get isError() {
322
323 const me = this;
324
325 return me.getConfigValue( "isError", false );
326 }
327
328 // noinspection JSUnusedGlobalSymbols
329 set isError( /** boolean */ val ) {
330
331 const me = this;
332
333 me.setConfigValue( "isError", val );
334 }
335
336 /**
337 * Returns a plain object representation of this response object.
338 *
339 * @public
340 * @param {string} [bodyProperty="strBody"] - Indicates how the body should
341 * be formatted within the returned object.
342 * @returns {{statusCode: *, headers: *, body: *}} Plain object
343 * representation of this response object.
344 */
345 toPlainObject( bodyProperty ) {
346
347 const me = this;
348
349 if ( bodyProperty !== "body" ) {
350
351 bodyProperty = "strBody";
352 }
353
354 return {
355 statusCode : me.statusCode,
356 headers : me.headers,
357 body : me[ bodyProperty ],
358 };
359 }
360
361 /**
362 * Serializes this collection into a JSON-API compatible object.
363 *
364 * @private
365 * @returns {Object} JSON-API compatible object.
366 */
367 _serializeToJsonApiObject() {
368
369 const me = this;
370
371 return me.toPlainObject( "strBody" );
372 }
373
374 /**
375 * Creates a JSON-API compatible scaffold for the response body [object].
376 *
377 * @private
378 * @returns {Object} Response body.
379 */
380 _createResponseBody() {
381
382 const me = this;
383
384 return {
385 jsonapi: {
386 version: "1.0",
387 },
388 meta: {
389 requestId : me.requestId,
390 seriesId : me.seriesId,
391 operationId : me.operationId,
392 stage : me.apiStage,
393 service : {
394 name : me.endpoint.serviceName,
395 version : me.endpoint.serviceVersion,
396 },
397 },
398 };
399 }
400};