Skip to content
This repository was archived by the owner on Jul 13, 2023. It is now read-only.

Commit 3de999e

Browse files
feat: deferred client initialization (#128)
This PR includes changes from googleapis/gapic-generator-typescript#317 that will move the asynchronous initialization and authentication from the client constructor to an `initialize()` method. This method will be automatically called when the first RPC call is performed. The client library usage has not changed, there is no need to update any code. If you want to make sure the client is authenticated _before_ the first RPC call, you can do ```js await client.initialize(); ``` manually before calling any client method.
1 parent fc79bf8 commit 3de999e

3 files changed

+112
-27
lines changed

src/v1beta1/recaptcha_enterprise_service_v1_beta1_client.ts

+60-23
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,13 @@ export class RecaptchaEnterpriseServiceV1Beta1Client {
4444
private _innerApiCalls: {[name: string]: Function};
4545
private _pathTemplates: {[name: string]: gax.PathTemplate};
4646
private _terminated = false;
47+
private _opts: ClientOptions;
48+
private _gaxModule: typeof gax | typeof gax.fallback;
49+
private _gaxGrpc: gax.GrpcClient | gax.fallback.GrpcClient;
50+
private _protos: {};
51+
private _defaults: {[method: string]: gax.CallSettings};
4752
auth: gax.GoogleAuth;
48-
recaptchaEnterpriseServiceV1Beta1Stub: Promise<{[name: string]: Function}>;
53+
recaptchaEnterpriseServiceV1Beta1Stub?: Promise<{[name: string]: Function}>;
4954

5055
/**
5156
* Construct an instance of RecaptchaEnterpriseServiceV1Beta1Client.
@@ -69,8 +74,6 @@ export class RecaptchaEnterpriseServiceV1Beta1Client {
6974
* app is running in an environment which supports
7075
* {@link https://developers.google.com/identity/protocols/application-default-credentials Application Default Credentials},
7176
* your project ID will be detected automatically.
72-
* @param {function} [options.promise] - Custom promise module to use instead
73-
* of native Promises.
7477
* @param {string} [options.apiEndpoint] - The domain name of the
7578
* API remote host.
7679
*/
@@ -101,26 +104,29 @@ export class RecaptchaEnterpriseServiceV1Beta1Client {
101104
// If we are in browser, we are already using fallback because of the
102105
// "browser" field in package.json.
103106
// But if we were explicitly requested to use fallback, let's do it now.
104-
const gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax;
107+
this._gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax;
105108

106109
// Create a `gaxGrpc` object, with any grpc-specific options
107110
// sent to the client.
108111
opts.scopes = (this
109112
.constructor as typeof RecaptchaEnterpriseServiceV1Beta1Client).scopes;
110-
const gaxGrpc = new gaxModule.GrpcClient(opts);
113+
this._gaxGrpc = new this._gaxModule.GrpcClient(opts);
114+
115+
// Save options to use in initialize() method.
116+
this._opts = opts;
111117

112118
// Save the auth object to the client, for use by other methods.
113-
this.auth = gaxGrpc.auth as gax.GoogleAuth;
119+
this.auth = this._gaxGrpc.auth as gax.GoogleAuth;
114120

115121
// Determine the client header string.
116-
const clientHeader = [`gax/${gaxModule.version}`, `gapic/${version}`];
122+
const clientHeader = [`gax/${this._gaxModule.version}`, `gapic/${version}`];
117123
if (typeof process !== 'undefined' && 'versions' in process) {
118124
clientHeader.push(`gl-node/${process.versions.node}`);
119125
} else {
120-
clientHeader.push(`gl-web/${gaxModule.version}`);
126+
clientHeader.push(`gl-web/${this._gaxModule.version}`);
121127
}
122128
if (!opts.fallback) {
123-
clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`);
129+
clientHeader.push(`grpc/${this._gaxGrpc.grpcVersion}`);
124130
}
125131
if (opts.libName && opts.libVersion) {
126132
clientHeader.push(`${opts.libName}/${opts.libVersion}`);
@@ -136,36 +142,38 @@ export class RecaptchaEnterpriseServiceV1Beta1Client {
136142
'protos',
137143
'protos.json'
138144
);
139-
const protos = gaxGrpc.loadProto(
145+
this._protos = this._gaxGrpc.loadProto(
140146
opts.fallback ? require('../../protos/protos.json') : nodejsProtoPath
141147
);
142148

143149
// This API contains "path templates"; forward-slash-separated
144150
// identifiers to uniquely identify resources within the API.
145151
// Create useful helper objects for these.
146152
this._pathTemplates = {
147-
assessmentPathTemplate: new gaxModule.PathTemplate(
153+
assessmentPathTemplate: new this._gaxModule.PathTemplate(
148154
'projects/{project}/assessments/{assessment}'
149155
),
150-
keyPathTemplate: new gaxModule.PathTemplate(
156+
keyPathTemplate: new this._gaxModule.PathTemplate(
151157
'projects/{project}/keys/{key}'
152158
),
153-
projectPathTemplate: new gaxModule.PathTemplate('projects/{project}'),
159+
projectPathTemplate: new this._gaxModule.PathTemplate(
160+
'projects/{project}'
161+
),
154162
};
155163

156164
// Some of the methods on this service return "paged" results,
157165
// (e.g. 50 results at a time, with tokens to get subsequent
158166
// pages). Denote the keys used for pagination and results.
159167
this._descriptors.page = {
160-
listKeys: new gaxModule.PageDescriptor(
168+
listKeys: new this._gaxModule.PageDescriptor(
161169
'pageToken',
162170
'nextPageToken',
163171
'keys'
164172
),
165173
};
166174

167175
// Put together the default options sent with requests.
168-
const defaults = gaxGrpc.constructSettings(
176+
this._defaults = this._gaxGrpc.constructSettings(
169177
'google.cloud.recaptchaenterprise.v1beta1.RecaptchaEnterpriseServiceV1Beta1',
170178
gapicConfig as gax.ClientConfig,
171179
opts.clientConfig || {},
@@ -176,18 +184,36 @@ export class RecaptchaEnterpriseServiceV1Beta1Client {
176184
// of calling the API is handled in `google-gax`, with this code
177185
// merely providing the destination and request information.
178186
this._innerApiCalls = {};
187+
}
188+
189+
/**
190+
* Initialize the client.
191+
* Performs asynchronous operations (such as authentication) and prepares the client.
192+
* This function will be called automatically when any class method is called for the
193+
* first time, but if you need to initialize it before calling an actual method,
194+
* feel free to call initialize() directly.
195+
*
196+
* You can await on this method if you want to make sure the client is initialized.
197+
*
198+
* @returns {Promise} A promise that resolves to an authenticated service stub.
199+
*/
200+
initialize() {
201+
// If the client stub promise is already initialized, return immediately.
202+
if (this.recaptchaEnterpriseServiceV1Beta1Stub) {
203+
return this.recaptchaEnterpriseServiceV1Beta1Stub;
204+
}
179205

180206
// Put together the "service stub" for
181207
// google.cloud.recaptchaenterprise.v1beta1.RecaptchaEnterpriseServiceV1Beta1.
182-
this.recaptchaEnterpriseServiceV1Beta1Stub = gaxGrpc.createStub(
183-
opts.fallback
184-
? (protos as protobuf.Root).lookupService(
208+
this.recaptchaEnterpriseServiceV1Beta1Stub = this._gaxGrpc.createStub(
209+
this._opts.fallback
210+
? (this._protos as protobuf.Root).lookupService(
185211
'google.cloud.recaptchaenterprise.v1beta1.RecaptchaEnterpriseServiceV1Beta1'
186212
)
187213
: // tslint:disable-next-line no-any
188-
(protos as any).google.cloud.recaptchaenterprise.v1beta1
214+
(this._protos as any).google.cloud.recaptchaenterprise.v1beta1
189215
.RecaptchaEnterpriseServiceV1Beta1,
190-
opts
216+
this._opts
191217
) as Promise<{[method: string]: Function}>;
192218

193219
// Iterate over each of the methods that the service provides
@@ -215,9 +241,9 @@ export class RecaptchaEnterpriseServiceV1Beta1Client {
215241
}
216242
);
217243

218-
const apiCall = gaxModule.createApiCall(
244+
const apiCall = this._gaxModule.createApiCall(
219245
innerCallPromise,
220-
defaults[methodName],
246+
this._defaults[methodName],
221247
this._descriptors.page[methodName] ||
222248
this._descriptors.stream[methodName] ||
223249
this._descriptors.longrunning[methodName]
@@ -231,6 +257,8 @@ export class RecaptchaEnterpriseServiceV1Beta1Client {
231257
return apiCall(argument, callOptions, callback);
232258
};
233259
}
260+
261+
return this.recaptchaEnterpriseServiceV1Beta1Stub;
234262
}
235263

236264
/**
@@ -364,6 +392,7 @@ export class RecaptchaEnterpriseServiceV1Beta1Client {
364392
] = gax.routingHeader.fromParams({
365393
parent: request.parent || '',
366394
});
395+
this.initialize();
367396
return this._innerApiCalls.createAssessment(request, options, callback);
368397
}
369398
annotateAssessment(
@@ -448,6 +477,7 @@ export class RecaptchaEnterpriseServiceV1Beta1Client {
448477
] = gax.routingHeader.fromParams({
449478
name: request.name || '',
450479
});
480+
this.initialize();
451481
return this._innerApiCalls.annotateAssessment(request, options, callback);
452482
}
453483
createKey(
@@ -531,6 +561,7 @@ export class RecaptchaEnterpriseServiceV1Beta1Client {
531561
] = gax.routingHeader.fromParams({
532562
parent: request.parent || '',
533563
});
564+
this.initialize();
534565
return this._innerApiCalls.createKey(request, options, callback);
535566
}
536567
getKey(
@@ -612,6 +643,7 @@ export class RecaptchaEnterpriseServiceV1Beta1Client {
612643
] = gax.routingHeader.fromParams({
613644
name: request.name || '',
614645
});
646+
this.initialize();
615647
return this._innerApiCalls.getKey(request, options, callback);
616648
}
617649
updateKey(
@@ -695,6 +727,7 @@ export class RecaptchaEnterpriseServiceV1Beta1Client {
695727
] = gax.routingHeader.fromParams({
696728
'key.name': request.key!.name || '',
697729
});
730+
this.initialize();
698731
return this._innerApiCalls.updateKey(request, options, callback);
699732
}
700733
deleteKey(
@@ -776,6 +809,7 @@ export class RecaptchaEnterpriseServiceV1Beta1Client {
776809
] = gax.routingHeader.fromParams({
777810
name: request.name || '',
778811
});
812+
this.initialize();
779813
return this._innerApiCalls.deleteKey(request, options, callback);
780814
}
781815

@@ -867,6 +901,7 @@ export class RecaptchaEnterpriseServiceV1Beta1Client {
867901
] = gax.routingHeader.fromParams({
868902
parent: request.parent || '',
869903
});
904+
this.initialize();
870905
return this._innerApiCalls.listKeys(request, options, callback);
871906
}
872907

@@ -913,6 +948,7 @@ export class RecaptchaEnterpriseServiceV1Beta1Client {
913948
parent: request.parent || '',
914949
});
915950
const callSettings = new gax.CallSettings(options);
951+
this.initialize();
916952
return this._descriptors.page.listKeys.createStream(
917953
this._innerApiCalls.listKeys as gax.GaxCall,
918954
request,
@@ -1026,8 +1062,9 @@ export class RecaptchaEnterpriseServiceV1Beta1Client {
10261062
* The client will no longer be usable and all future behavior is undefined.
10271063
*/
10281064
close(): Promise<void> {
1065+
this.initialize();
10291066
if (!this._terminated) {
1030-
return this.recaptchaEnterpriseServiceV1Beta1Stub.then(stub => {
1067+
return this.recaptchaEnterpriseServiceV1Beta1Stub!.then(stub => {
10311068
this._terminated = true;
10321069
stub.close();
10331070
});

0 commit comments

Comments
 (0)