feat: Add full support for Universe Domain#1604
Conversation
to be passed in
There was a problem hiding this comment.
I am a bit confused by these changes.
- It seems like for the GAPIC clients, the universe domain needs to be set in two places - in the
servicePathand theoptions. Why not just let the GAPIC determine their ownservicePath? If this is just keeping with the existing paradigm, then that's fine - The
adminOptionsandinstanceAdminOptionsare formed by merging the options from the existingBigtableTableAdminClientandBigtableInstanceAdminClient. Why? It seems circular to me - we create the options for those GAPICs and then save the options back from the GAPICs?
| * for `universeDomain` or `universe_domain` in the gax options, and finally | ||
| * falls back to the `GOOGLE_CLOUD_UNIVERSE_DOMAIN` environment variable. | ||
| * If a universe domain is found, it returns an object containing the | ||
| * `universeDomain` property; otherwise, it returns `null`. |
There was a problem hiding this comment.
it may simplify things to have universeDomain never be null, and always default to googleapis.com when set. Although, because you have a specific getUniverseDomainOnly method, I am assuming you have a specific reason for doing it this way? If so, what is it?
There was a problem hiding this comment.
The reason getUniverseDomainOptions returns null is that the return value is used in an Object.assign call. The behaviour of Object.assign is that it does nothing to the object being assigned, in this case, the Gapic client options if the object being assigned to it is null.
So the behaviour we want that we are getting with this code is don't modify the gapic client options when null gets returned.
| servicePath: | ||
| customEndpointBaseUrl || | ||
| getDomain('bigtable', options.BigtableClient), | ||
| getDomain('bigtable', options, options.BigtableClient), |
There was a problem hiding this comment.
What does this look like when the user provides universe domain in the GAPIC client but not in the handwritten client?
src/index.ts
Outdated
| options?.universeDomain ?? | ||
| gaxOpts?.universeDomain ?? | ||
| gaxOpts?.universe_domain ?? | ||
| universeDomainEnvVar |
There was a problem hiding this comment.
what is the difference between options.universeDomain and gaxOpts.universeDomain from a user perspective? What does it look like when one overrides the other?
There was a problem hiding this comment.
gaxOpts is the settings the user provided for the specific Gapic client and options is the options provided to the handwritten layer. We discussed offline that we should really allow the gapic options to take priority over the handwritten layer options so I can apply the change to make gaxOpts?.universeDomain come first.
There was a problem hiding this comment.
Ok. gaxOpts?.universeDomain comes first now
| const dataOptions = Object.assign( | ||
| {}, | ||
| baseOptions, | ||
| getUniverseDomainOptions(options, options.BigtableClient), |
There was a problem hiding this comment.
Why not just be opinionated here and pass in getDomain?
| return ( | ||
| options?.universeDomain ?? | ||
| gaxOpts?.universeDomain ?? | ||
| gaxOpts?.universe_domain ?? |
There was a problem hiding this comment.
Why do we check the snake-case universe_domain for the gaxOpts but not for the options opts?
There was a problem hiding this comment.
This something that Alex decided on a while back. I'm not entirely sure why we do it, but we do it in generated gapic clients too, so it's in all of the libraries. (At least the ones I've seen.)
There was a problem hiding this comment.
Should it be added to options then as well? e.g.
return (
options?.universeDomain ??
options?.universe_domain ??
gaxOpts?.universeDomain ??
gaxOpts?.universe_domain ??
universeDomainEnvVar ??
}
Or should snake-case be marked deprecated so that newer clients (e.g. this one) can ignore it?
There was a problem hiding this comment.
So the BigtableOptions passed into the handwritten layer at https://github.com/googleapis/nodejs-bigtable/blob/main/src/index.ts#L82 extend GoogleAuthOptions and only support camel case according to the screenshot:

But the universe domain for the Gapic ClientOptions type supports both camel case and snake case:
There was a problem hiding this comment.
I have a suspicion that the reason we did this is that an earlier version of the spec wanted snake case, and then we decided to make it camel case to match everything else in Node. But the person who wrote it has left, so I'm not 100% sure. Let's see if there is a bread crumb trail...
...Unfortunately no. It looks like it was one big commit without further explanation.
In response to 1. Because as I said in one of the PR comments, if we don't set universeDomain in the options then the test fails! When universe domain is set in a client option or using an environment variable by the user then universe domain has to be set on the gapic client options for the test to pass. Try it out yourself. In response to 2. The client library worked this way before and I don't want to change the way it works because the minimal amount of changes necessary to support universe domains is ideal. I think these values adminOptions and dataOptions are saved so that they are ready when a gapic client gets initialized just before a request is made. If you want to change the way gapic options are handled in nodejs-bigtable then I would suggest filing a separate bug. |
…h' of https://github.com/googleapis/nodejs-bigtable into universe-domain-service-path-ordinary-new-fix-one-branch
I'm behind this idea. If it was already that way before, let's leave it for now and circle back if it's weird. |
…into universe-domain-service-path-ordinary-new-fix-one-branch # Conflicts: # system-test/service-path.ts
🤖 I have created a release *beep* *boop* --- ## [6.1.0](https://togithub.com/googleapis/nodejs-bigtable/compare/v6.0.0...v6.1.0) (2025-05-30) ### Features * Add full support for Universe Domain ([#1604](https://togithub.com/googleapis/nodejs-bigtable/issues/1604)) ([4562e23](https://togithub.com/googleapis/nodejs-bigtable/commit/4562e2329e734c0c9d9f00cfa83aa2be13e9a7fe)) --- This PR was generated with [Release Please](https://togithub.com/googleapis/release-please). See [documentation](https://togithub.com/googleapis/release-please#release-please).

Description
Adds local testing for all universe domain use cases with a service account. Adds support for
universeDomainoption passed into the handwritten client. Passes universeDomain to the Gapic client to solve theError: The configured universe domain (googleapis.com) does not match the universe domain found in the credentials (apis-tpczero.goog)error.Also, an upstream change from google-gax is now providing more information in errors so some assert statements needed to be slightly modified.
Impact
Fixes all universe domain use case and provides code so that we can continue to validate it going forward.
Testing
Added tests to be run locally with the service account credentials for the project with the universe domain. Adding new service account credentials so that this can be tested in the CI pipeline is out of scope.
Additional Information
An Alternative was considered where we only pass a service path into the gapic client when a custom API is provided, but that produced an error that says
Error: 14 UNAVAILABLE: Name resolution failed for target dns:null:443 before any response was received..