-
Notifications
You must be signed in to change notification settings - Fork 591
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Integration with Gapic-generated code #1463
Comments
Hello! Is there any "getting started" material for those projects? Example code would be very helpful as well. |
Sorry, we don't 😞 |
Hmm, I've noticed that the handling of grpc-client is significantly different. Our code generator will generate the code assuming to obtain Let me keep the existing scheme for now, but probably this common library and GAX would converge in some way in the future. |
No problem, I'm excited to see the PR.
Yeah, that would be great! I'd really like if we deferred to GAX for retries/error handling best practices. |
Proposals that came out of my meeting with @jmuk, using the Speech API as an example: Variant 1 - expose auto-gen on exported moduleImporting// Initialize hand-written client:
var Speech = require('@google-cloud/speech');
var speech = Speech({
keyFilename: '/path/to/keyfile.json',
projectId: 'grape-spaceship-123'
});
// Use an idiomatic convenience method, which was implemented using
// the v2 "bare metal" method shown below
speech.createDetectJob(...);
// Initialize auto-generated client for v2:
var speech_v2 = Speech.v2();
// Use a "bare metal" grpc method
speech_v2.asyncrecognize(...);
//Initialize auto-generated client for v1:
var speech_v1 = Speech.v1();
// Use a "bare metal" grpc method
speech_v1.asyncrecognize(...); This requires that the exported function Speech (...) {...}
Speech.v2 = require('./v2');
Speech.v1 = require('./v1');
module.exports = Speech; Getting auto-gen updates integrated into gcloud-node would require a little more File structure
What if the API doesn't have or need a hand-written layer?The root // Initialize hand-written client:
var simpleapi = require('@google-cloud/simpleapi')();
// Initialize auto-generated client for v2 of simpleapi:
var simpleapi_v2 = simpleapi.v2();
assert.deepEqual(simpleapi, simpleapi_v2) Variant 2 - user imports auto-gen on separate pathImporting// Initialize hand-written client:
var speech = require('@google-cloud/speech')({
keyFilename: '/path/to/keyfile.json',
projectId: 'grape-spaceship-123'
});
// Use an idiomatic convenience method, which was implemented using
// the v2 "bare metal" method shown below
speech.createDetectJob(...);
// Initialize auto-generated client for v2:
var speech_v2 = require('@google-cloud/speech/v2')();
// Use a "bare metal" grpc method
speech_v2.asyncrecognize(...);
// Initialize auto-generated client for v1:
var speech_v1 = require('@google-cloud/speech/v1')();
// Use a "bare metal" grpc method
speech_v1.asyncrecognize(...); This does NOT require the exported function Speech (...) {...}
module.exports = Speech; Instead the user gets a hold of an auto-gen client by importing it from a deeper path: var speech_v1 = require('@google-cloud/speech/v1')(); The updated folder structure in this variant allows Getting auto-gen updates integrated into gcloud-node would be a little easier, File structure
What if the API doesn't have or need a hand-written layer?The root // Initialize hand-written client:
var simpleapi = require('@google-cloud/simpleapi')();
// Initialize auto-generated client for v2 of simpleapi:
var simpleapi_v2 = require('@google-cloud/simpleapi/v2')();
assert.deepEqual(simpleapi, simpleapi_v2) |
Variant 1 has my vote. That makes the transition seamless to the users that just want the convenience API, then uses API versions as the concise, logical entry points to the users that need full access. 👍 |
One additional thought I had is that the hand-written layer inevitably must instantiate an auto-gen client in order to use it to implement idiomatic methods, thus, the exposed hand-written client should make its auto-gen client methods available on itself, for example: // Initialize hand-written client:
var Speech = require('@google-cloud/speech');
var speech = Speech({
keyFilename: '/path/to/keyfile.json',
projectId: 'grape-spaceship-123'
});
// use hand-written method
speech.createDetectJob(...);
// now use bare-metal method, a pass-thru to auto-gen client
speech.asyncrecognize(...);
// This is wasteful, as the v2 auto-gen client has now been initialized twice.
// I shouldn't HAVE to do this just to get to that bare-metal method
var speech_v2 = Speech.v2();
speech_v2.asyncrecognize(...); |
I actually prefer the separation, but we also have name clashing to watch out for. An alternative to a call to "version()" could be just dropping the methods inside a "version" property on the instantiated object: pubsub.getTopics() |
Actually not sure about that ^. If required scopes change between API releases, we couldn't re-use an auth client. So without a function call to create a new "v2()", we would have to use some kind of lazy-instantiating code that creates a new auth-client. That often means confusing code and unintended side effects. I personally don't mind the "v2()" call and like the separation implied by that hierarchy, but happy to hear other thoughts on the matter. |
You probably right. If someone wants to use a bare-metal method, they can just instantiate an auto-gen client. However, documentation for it is hard to generalize because the auto-gen clients are namespaced by a version. The user would have to be aware of the API version the want to use in order to do it, which is an extra thing to have to think about. |
Hi, I pushed the initial patch for Speech API client as jmuk@ec6ecf7 Please take a look for how it goes. A minor difference is -- we generate a 'class' (or a service object) per grpc service. Because an API can consist of multiple services, it will be:
rathrer than |
Regarding the auth-tokens (sorry I'm late on the response): GAX depends on the auth library ("google-auth-library"), the generated code would (and should) support the customized authentication as the auth library accepts. |
That makes sense. Any opinions on if we should try to avoid making users deal with // auto-gen layer
- var api = new Speech.v1.SpeechApi();
+ var api = speech.v1.speechApi();
api.nonStreamingRecognize(...); |
Okay, thanks. I'll have to make an issue there to see if they can support that feature. |
Hm, I didn't consider the option about omitting |
Yeah, you can see here how the Speech client does it: https://github.com/jmdobry/gcloud-node/blob/speech/packages/speech/src/index.js#L101 |
- language_service_api.js and language_service_client_config.json: auto-generated - v1beta1/index.js: manually written - index.js and package.json: manually modified Updates googleapis#1463
I've created #1476 for adding Gapic-created code for Cloud-Language API. This was created because Speech API is still in PR, and I want to request the review for the auto-generated code. Please take a look at this. |
For authentication -- GAX actually invokes 'getApplicationDefault', which might not fit greatly with gcloud-node parameters. I've filed googleapis/gax-nodejs#31 for this purpose. |
As we discussed in googleapis/google-cloud-node#1463', many of auth parameters will be called in a initialization of the module itself and then used later. For this purpose, GAX also serves an object which keeps the auth data and handle its feature under the same context. This also offers a new dependency of google-auto-auth library instead of google-auth-library, and supports nice optional parameters like keyFile.
As we discussed in googleapis/google-cloud-node#1463', many of auth parameters will be called in a initialization of the module itself and then used later. For this purpose, GAX also serves an object which keeps the auth data and handle its feature under the same context. This also offers a new dependency of google-auto-auth library instead of google-auth-library, and supports nice optional parameters like keyFile.
- language_service_api.js and language_service_client_config.json: auto-generated - v1beta1/index.js: manually written - index.js and package.json: manually modified Updates googleapis#1463
Just for the record: we continued the discussion about loading the generated files at #1476, and it seems we agreed to take Variant 1 style. var speech = require('@google-cloud/speech');
var speechV1 = speech.v1({keyFile: ...});
var api = speechV1.SpeechApi();
api.nonStreamingRecognize(...); |
* Refactor gRPC and Auth situation. As we discussed in googleapis/google-cloud-node#1463', many of auth parameters will be called in a initialization of the module itself and then used later. For this purpose, GAX also serves an object which keeps the auth data and handle its feature under the same context. This also offers a new dependency of google-auto-auth library instead of google-auth-library, and supports nice optional parameters like keyFile. * Minor style fix
- language_service_api.js and language_service_client_config.json: auto-generated - v1beta1/index.js: manually written - index.js and package.json: manually modified Updates googleapis#1463
- language_service_api.js and language_service_client_config.json: auto-generated - v1beta1/index.js: manually written - index.js and package.json: manually modified Updates googleapis#1463
I'm in charge of Gapic codegen and GAX for NodeJS
It was an independent effort, but recently we reached to an agreement that bringing the generated code into a part of gcloud itself.
It's still unclear to me where the generated code will be located and how these files are accessible from users, so this is an issue to discuss about these things.
The text was updated successfully, but these errors were encountered: