11const https = require ( 'https' ) ;
2+ const { ApertureClient } = require ( "@fluxninja/aperture-js" ) ;
23
34exports . makeRequest = makeRequest ;
5+ exports . makeRequestWithRateLimit = makeRequestWithRateLimit ;
6+
7+ var apertureClient ;
8+
9+ function getApertureClient ( ) {
10+ if ( ! apertureClient ) {
11+ apertureClient = new ApertureClient ( {
12+ address : process . env . APERTURE_SERVICE_ADDRESS ,
13+ apiKey : process . env . APERTURE_API_KEY ,
14+ } ) ;
15+ }
16+ return apertureClient ;
17+ }
418
519/**
620 * Sends an HTTPS request based on the specified method and options
721 * This function returns a Promise that resolves with the response and data received from the server
822 * @param {string } method - The HTTP method to use (e.g., 'GET', 'POST').
923 * @param {string } url - The URL to which the request is sent.
10- * @param {Object } [options] - The options for the request. This includes headers, request body (for POST/PUT), etc.
24+ * @param {Object } [requestOptions] - The options for the request. This includes headers, request body (for POST/PUT), etc.
25+ * @param {Object } [requestOptions.body] - The data that needs to be sent with the request, used for POST/PUT requests
26+ * @param {Object } [requestOptions.headers] - The headers that needs to be sent with the request
1127 * @returns {Promise<{res: https.IncomingMessage, data: string}> } A Promise that resolves with the response object and the body data as a string.
1228 * @throws {Error } Throws an error if the request cannot be completed
1329 *
@@ -23,13 +39,13 @@ exports.makeRequest = makeRequest;
2339 * }
2440 * }
2541 * */
26- async function makeRequest ( method , url , options ) {
42+ async function makeRequest ( method , url , requestOptions ) {
2743 return new Promise ( ( resolve , reject ) => {
2844 // Ensure options is an object and set the method
29- options = typeof options === 'object' ? options : { } ;
30- options . method = method ;
45+ requestOptions = typeof requestOptions === 'object' ? requestOptions : { } ;
46+ requestOptions . method = method ;
3147
32- const req = https . request ( url , options , res => {
48+ const req = https . request ( url , requestOptions , res => {
3349 // Handle HTTP response stream
3450 let data = '' ;
3551 res . on ( 'data' , chunk => data += chunk ) ;
@@ -42,10 +58,63 @@ async function makeRequest(method, url, options) {
4258 } ) ;
4359
4460 // Handle POST/PUT data if provided
45- if ( options . data ) {
46- req . write ( options . data ) ;
61+ if ( requestOptions . data ) {
62+ req . write ( requestOptions . data ) ;
4763 }
4864
4965 req . end ( ) ;
5066 } ) ;
51- }
67+ }
68+
69+
70+ /**
71+ * Sends an HTTPS request with rate limiting. The function checks if the request is allowed by the rate limiter,
72+ * and if so, sends an HTTPS request based on the specified method and options. This function returns a Promise
73+ * that resolves with the response and data received from the server or rejects if an error occurs or the rate limit is exceeded.
74+ *
75+ * @param {string } method - The HTTP method to use (e.g., 'GET', 'POST').
76+ * @param {string } url - The URL to which the request is sent.
77+ * @param {Object } [options] - The options for the request. This includes headers, request body (for POST/PUT), etc.
78+ * @param {Object } [options.rateLimitOptions] - Options related to rate limits
79+ * @param {Object } [options.body] - The data that needs to be sent with the request, used for POST/PUT requests
80+ * @param {Object } [options.headers] - The headers that needs to be sent with the request
81+ * @returns {Promise<{res: https.IncomingMessage, data: string}> } A Promise that resolves with the response object and the body data as a string.
82+ * @throws {Error } Throws an error if the rate limit is exceeded or if an invalid argument is passed.
83+ *
84+ * @example
85+ * // Example usage for a GET request within an async function
86+ * async function getExample() {
87+ * try {
88+ * const { res, data } = await makeRequest('GET', 'https://example.com');
89+ * console.log('Status Code:', res.statusCode);
90+ * console.log('Body:', data);
91+ * } catch (error) {
92+ * console.error('Error:', error.message);
93+ * }
94+ * }
95+ * */
96+ async function makeRequestWithRateLimit ( method , url , requestOptions ) {
97+ const flow = await apertureClient . startFlow ( "external-api-request" , {
98+ labels : {
99+ url : url ,
100+ } ,
101+ grpcCallOptions : {
102+ deadline : Date . now ( ) + 300 , // ms
103+ } ,
104+ } ) ;
105+
106+ if ( flow . shouldRun ( ) ) {
107+ // Add business logic to process incoming request
108+ console . log ( "Request accepted. Processing..." ) ;
109+ const { res, data} = await makeRequest ( ...arguments )
110+ return { res, data}
111+ } else {
112+ console . log ( "Request rate-limited. Try again later." ) ;
113+ // Handle flow rejection
114+ flow . setStatus ( FlowStatus . Error ) ;
115+ }
116+
117+ if ( flow ) {
118+ flow . end ( ) ;
119+ }
120+ }
0 commit comments