-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdao-endpoint.js
186 lines (154 loc) · 5.92 KB
/
dao-endpoint.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
/*
* =============================================================================
* Endpoint request class. DAO/Template
* -----------------------------------------------------------------------------
*
* Barebones API request to an endpoint. Can also be used as a template to
* create additional DAO object classes.
*
* The class can be used as a template and modified to provide additional
* logic, query, filtering, and manipulation before/after data is sent/received
* via the APIRequest class.
*
* The class itself is not exposed, instead various functions can be used
* to access the class. For exmaple, getDataDirectFromURI(connection, data)
*
* The connection parameter is used to pass connection information to the
* API (host, path, query, etc).
*
* The data parameter is optional and can be left off. However, it can be used
* to pass additional information to the class to perform before/after logic.
*
* @example
* // access function that utilizes the class
* const getDataDirectFromURI = async (connection, data = null) => {
* return (new Endpoint(connection).get());
* };
*/
/*
* -----------------------------------------------------------------------------
* Object definitions
* -----------------------------------------------------------------------------
*/
/**
* @typedef ConnectionObject
* @property {Object} connection
* @property {string} connection.method
* @property {string} connection.uri
* @property {string} connection.protocol http or https
* @property {string} connection.host
* @property {string} connection.path
* @property {string} connection.body
* @property {object} connection.parameters
* @property {object} connection.headers
* @property {object} connection.options
* @property {number} connection.options.timeout
* @property {string} connection.note
*/
/*
* -----------------------------------------------------------------------------
*/
"use strict";
const tools = require("./tools/index.js");
/**
*
* @param {ConnectionObject} connection An object with details about the connection (method, uri, host, etc)
* @param {*} data Additional data to perform a query for the request, or transformation of the response within the DAO object. This data is not directly sent to the endpoint. It is used within the DAO object to transform the request and/or response. Any data sent to the endpoint should be in the connection or handled within the DAO
* @returns {object} The response
*/
const getDataDirectFromURI = async (connection, data = null) => {
return (new Endpoint(connection).get());
};
/**
* A bare bones request to an endpoint. Can be used as a template to
* create more elaboarate requests.
*/
class Endpoint {
/**
*
* @param {ConnectionObject} connection An object with connection data
*/
constructor(connection) {
this.response = null;
this.request = {
method: this._setRequestSetting(connection, "method", "GET"),
uri: this._setRequestSetting(connection, "uri", ""),
protocol: this._setRequestSetting(connection, "protocol", "https"),
host: this._setRequestSetting(connection, "host", ""),
path: this._setRequestSetting(connection, "path", ""),
body: this._setRequestSetting(connection, "body", null),
note: this._setRequestSetting(connection, "note", "Get data from endpoint"),
parameters: this._setRequestSetting(connection, "parameters", null),
headers: this._setRequestSetting(connection, "headers", null),
options: this._setRequestSetting(connection, "options", null)
};
};
/**
* Takes the connection object, checks for the key provided and if the key
* exists it returns its value. Otherwise it returns the default value.
* @param {ConnectionObject} connection The connection object to check for the existence of a key
* @param {string} key The key to check for and return the value from connection
* @param {*} defaultValue The value to use if the key is not found in the connection object
* @returns {*} Either the value of the key if found in the connection object, or the default value
*/
_setRequestSetting(connection, key, defaultValue) {
if (!(key in connection)) {
connection[key] = defaultValue;
}
return connection[key];
};
/**
* This is the function used by the accessor method after the constructor
* is called.
*
* As a template, it can be modified to perform additional checks,
* operations, etc before or after sending the call.
*
* @example
* // access function that utilizes the class
* const getDataDirectFromURI = async (connection, data = null) => {
* return (new Endpoint(connection).get());
* };
* @returns {object} Response data from the completed request
*/
async get() {
if (this.response === null) {
// send the call
try {
tools.DebugAndLog.debug("Sending call", this.request);
this.response = await this._call();
// if it is not JSON we don't convert
try {
let body = null;
if ( this.response.body !== "" && this.response.body !== null ) {
body = JSON.parse(this.response.body);
}
this.response.body = body;
} catch (error) {
tools.DebugAndLog.debug("This isn't JSON so we'll keep as text and do nothing. This isn't a true error.");
}
} catch (error) {
tools.DebugAndLog.error(`Error in call to remote endpoint (${this.request.note}): ${error.message}`, error.stack);
}
}
return this.response;
}
/**
* An internal function that actually makes the call to APIRequest class
* @returns {object} Response data from the completed request
*/
async _call() {
var response = null;
try {
var apiRequest = new tools.APIRequest(this.request);
response = await apiRequest.send();
} catch (error) {
tools.DebugAndLog.error(`Error in call (${this.request.note}): ${error.message}`, error.stack);
response = tools.APIRequest.responseFormat(false, 500, "Error in call()");
}
return response;
};
};
module.exports = {
getDataDirectFromURI
};